update dotnet/oryx features to use recommended install location for dotnet6 (#91)

* use default jammy apt feed to mitigate jammy/oryx install issues

* remove old comment

* jammy first tries default apt repo

* refactoring

* glob friendly and tests

* test files

* better greps

* correct path

* DEBIAN_FRONTEND global in oryx install script

* remove set -e from dotnet script to handle errors ourselves
This commit is contained in:
Josh Spicer 2022-08-16 17:33:25 -04:00 committed by GitHub
parent ea4eaf2a7a
commit ef87daf5af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 178 additions and 105 deletions

3
.devcontainer.json Normal file
View file

@ -0,0 +1,3 @@
{
"postCreateCommand": "npm install -g @devcontainers/cli"
}

View file

@ -8,7 +8,7 @@ on:
jobs: jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'no-ci') && !contains(github.event.head_commit.message, 'CI ignore')" if: "!contains(github.event.head_commit.message, 'no-ci') && !contains(github.event.head_commit.message, 'CI ignore') && !contains(github.event.head_commit.message, 'Automated documentation update')"
continue-on-error: true continue-on-error: true
strategy: strategy:
matrix: matrix:

View file

@ -1,15 +0,0 @@
name: "test"
on:
pull_request:
paths-ignore:
- ./**/oryx/**
- ./**/java/**
- ./**/dotnet/**
- ./**/php/**
- ./**/node/**
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: 'echo "No build required ; Temporary tweak for merging the PRs until branch protection rules are updated"'

View file

@ -5,7 +5,7 @@ on:
jobs: jobs:
detect-changes: detect-changes:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'no-ci') && !contains(github.event.head_commit.message, 'CI ignore')" if: "!contains(github.event.head_commit.message, 'no-ci') && !contains(github.event.head_commit.message, 'CI ignore') && !contains(github.event.head_commit.message, 'Automated documentation update')"
outputs: outputs:
features: ${{ steps.filter.outputs.changes }} features: ${{ steps.filter.outputs.changes }}
steps: steps:

View file

@ -9,7 +9,7 @@ on:
jobs: jobs:
scenarios: scenarios:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'no-ci') && !contains(github.event.head_commit.message, 'CI ignore')" if: "!contains(github.event.head_commit.message, 'no-ci') && !contains(github.event.head_commit.message, 'CI ignore') && !contains(github.event.head_commit.message, 'Automated documentation update')"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View file

@ -8,8 +8,8 @@
"type": "string", "type": "string",
"proposals": [ "proposals": [
"latest", "latest",
"6.0", "6",
"5.0", "5",
"3.1" "3.1"
], ],
"default": "latest", "default": "latest",

View file

@ -30,9 +30,6 @@ DOTNET_VERSION_CODENAMES_REQUIRE_OLDER_LIBSSL_1="buster bullseye bionic focal hi
# alongside DOTNET_VERSION, but not set as default. # alongside DOTNET_VERSION, but not set as default.
ADDITIONAL_VERSIONS=${ADDITIONALVERSIONS:-""} ADDITIONAL_VERSIONS=${ADDITIONALVERSIONS:-""}
# Exit on failure.
set -e
# Setup STDERR. # Setup STDERR.
err() { err() {
echo "(!) $*" >&2 echo "(!) $*" >&2
@ -155,13 +152,13 @@ apt_cache_package_and_version_soft_match() {
local exit_on_no_match="${3:-true}" local exit_on_no_match="${3:-true}"
local major_minor_version local major_minor_version
major_minor_version="$(echo "${requested_version}" | cut -d "." --field=1,2)"
package_name="$(apt-cache search "${partial_package_name}-[0-9].[0-9]" | awk -F" - " '{print $1}' | grep -m 1 "${partial_package_name}-${major_minor_version}")"
# Ensure we've exported useful variables # Ensure we've exported useful variables
. /etc/os-release . /etc/os-release
local architecture="$(dpkg --print-architecture)" local architecture="$(dpkg --print-architecture)"
major_minor_version="$(echo "${requested_version}" | cut -d "." --field=1,2)"
package_name="$(apt-cache search "${partial_package_name}-[0-9].[0-9]" | awk -F" - " '{print $1}' | grep -m 1 "${partial_package_name}-${major_minor_version}")"
dot_escaped="${requested_version//./\\.}" dot_escaped="${requested_version//./\\.}"
dot_plus_escaped="${dot_escaped//+/\\+}" dot_plus_escaped="${dot_escaped//+/\\+}"
# Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/
@ -170,14 +167,14 @@ apt_cache_package_and_version_soft_match() {
fuzzy_version="$(apt-cache madison ${package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${version_regex}")" fuzzy_version="$(apt-cache madison ${package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${version_regex}")"
set -e set -e
if [ -z "${fuzzy_version}" ]; then if [ -z "${fuzzy_version}" ]; then
echo "(!) No full or partial for package \"${package_name}\" match found in apt-cache for \"${requested_version}\" on OS ${ID} ${VERSION_CODENAME} (${architecture})." echo "(!) No full or partial for package \"${partial_package_name}\" (resolved: \"${package_name}\") match found in apt-cache for \"${requested_version}\" on OS ${ID} ${VERSION_CODENAME} (${architecture})."
if $exit_on_no_match; then if $exit_on_no_match; then
echo "Available versions:" echo "Available versions:"
apt-cache madison ${package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' apt-cache madison ${package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+'
exit 1 # Fail entire script exit 1 # Fail entire script
else else
echo "Continuing to fallback method (if available)" echo "Continuing to fallback method if available"
return 1; return 1;
fi fi
fi fi
@ -194,7 +191,7 @@ apt_cache_package_and_version_soft_match() {
} }
# Install .NET CLI using apt-get package installer # Install .NET CLI using apt-get package installer
install_using_apt() { install_using_apt_from_microsoft_repo() {
local sdk_or_runtime="$1" local sdk_or_runtime="$1"
local dotnet_major_minor_version local dotnet_major_minor_version
export DOTNET_PACKAGE="dotnet-${sdk_or_runtime}" export DOTNET_PACKAGE="dotnet-${sdk_or_runtime}"
@ -206,7 +203,7 @@ install_using_apt() {
get_common_setting MICROSOFT_GPG_KEYS_URI get_common_setting MICROSOFT_GPG_KEYS_URI
curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list
apt-get update apt-get update -y
if [ "${DOTNET_VERSION}" = "latest" ] || [ "${DOTNET_VERSION}" = "lts" ]; then if [ "${DOTNET_VERSION}" = "latest" ] || [ "${DOTNET_VERSION}" = "lts" ]; then
DOTNET_VERSION="" DOTNET_VERSION=""
@ -214,18 +211,38 @@ install_using_apt() {
else else
# Sets DOTNET_VERSION and DOTNET_PACKAGE if matches found. # Sets DOTNET_VERSION and DOTNET_PACKAGE if matches found.
apt_cache_package_and_version_soft_match DOTNET_VERSION DOTNET_PACKAGE false apt_cache_package_and_version_soft_match DOTNET_VERSION DOTNET_PACKAGE false
if [ "$?" != 0 ]; then
echo "Failed to find requested version."
return 1
fi
if [[ $(dotnet --version) == *"${DOTNET_VERSION}"* ]] ; then if [[ $(dotnet --version) == *"${DOTNET_VERSION}"* ]] ; then
echo "Dotnet version ${DOTNET_VERSION} is already installed" echo "Dotnet version ${DOTNET_VERSION} is already installed"
exit 1
fi
if [ "$?" != 0 ]; then
return 1 return 1
fi fi
fi fi
if ! (apt-get install -yq ${DOTNET_PACKAGE}${DOTNET_VERSION}); then echo "Installing '${DOTNET_PACKAGE}${DOTNET_VERSION}'..."
apt-get install -yq ${DOTNET_PACKAGE}${DOTNET_VERSION}
if [ "$?" != 0 ]; then
echo "Failed to complete apt install of ${DOTNET_PACKAGE}${DOTNET_VERSION}"
return 1
fi
}
install_using_default_apt_repo() {
DOTNET_PACKAGE="dotnet6"
apt_get_update_if_needed
if [[ "${DOTNET_VERSION}" = "latest" ]] || [[ "${DOTNET_VERSION}" = "lts" ]] || [[ ${DOTNET_VERSION} = "6"* ]]; then
if ! (apt-get install -yq ${DOTNET_PACKAGE}); then
echo "Failed to install 'dotnet6' package from default apt repo."
return 1
fi
else
echo "The provided dotnet version is not distributed in this distro's default apt repo."
return 1 return 1
fi fi
} }
@ -379,12 +396,15 @@ install_using_dotnet_releases_url() {
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
# Dotnet 3.1 and 5.0 are not supported on Ubuntu 22.04 (jammy)+, . /etc/os-release
architecture="$(dpkg --print-architecture)"
# Dotnet 3.1 and 5 are not supported on Ubuntu 22.04 (jammy)+,
# due to lack of libssl3.0 support. # due to lack of libssl3.0 support.
# See: https://github.com/microsoft/vscode-dev-containers/issues/1458#issuecomment-1135077775 # See: https://github.com/microsoft/vscode-dev-containers/issues/1458#issuecomment-1135077775
# NOTE: This will only guard against installation of the dotnet versions we propose via 'features'. # NOTE: This will only guard against installation of the dotnet versions we propose via 'features'.
# The user can attempt to install any other version at their own risk. # The user can attempt to install any other version at their own risk.
if [[ "${DOTNET_VERSION}" = "3.1" ]] || [[ "${DOTNET_VERSION}" = "5.0" ]]; then if [[ "${DOTNET_VERSION}" = "3"* ]] || [[ "${DOTNET_VERSION}" = "5"* ]]; then
if [[ ! "${DOTNET_VERSION_CODENAMES_REQUIRE_OLDER_LIBSSL_1}" = *"${VERSION_CODENAME}"* ]]; then if [[ ! "${DOTNET_VERSION_CODENAMES_REQUIRE_OLDER_LIBSSL_1}" = *"${VERSION_CODENAME}"* ]]; then
err "Dotnet ${DOTNET_VERSION} is not supported on Ubuntu ${VERSION_CODENAME} due to a change in the 'libssl' dependency across distributions.\n Please upgrade your version of dotnet, or downgrade your OS version." err "Dotnet ${DOTNET_VERSION} is not supported on Ubuntu ${VERSION_CODENAME} due to a change in the 'libssl' dependency across distributions.\n Please upgrade your version of dotnet, or downgrade your OS version."
exit 1 exit 1
@ -405,18 +425,20 @@ fi
# Install the .NET CLI # Install the .NET CLI
echo "(*) Installing .NET CLI..." echo "(*) Installing .NET CLI..."
. /etc/os-release
architecture="$(dpkg --print-architecture)"
CHANGE_OWNERSHIP="false" CHANGE_OWNERSHIP="false"
if [[ "${DOTNET_ARCHIVE_ARCHITECTURES}" = *"${architecture}"* ]] && [[ "${DOTNET_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]] && [[ "${INSTALL_USING_APT}" = "true" ]]; then if [[ "${DOTNET_ARCHIVE_ARCHITECTURES}" = *"${architecture}"* ]] && [[ "${DOTNET_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]] && [[ "${INSTALL_USING_APT}" = "true" ]]; then
echo "Detected ${VERSION_CODENAME} on ${architecture}. Attempting to install dotnet from apt" echo "Detected ${VERSION_CODENAME} on ${architecture}. Attempting to install dotnet from apt"
install_using_apt "${DOTNET_SDK_OR_RUNTIME}"
install_using_default_apt_repo || install_using_apt_from_microsoft_repo "${DOTNET_SDK_OR_RUNTIME}"
if [ "$?" != 0 ]; then
echo "Could not install requested version from apt on current distribution."
exit 1
fi
else else
if [[ "${INSTALL_USING_APT}" = "false" ]]; then if [[ "${INSTALL_USING_APT}" = "false" ]]; then
echo "Installing dotnet from releases url" echo "Installing dotnet from releases url"
else else
echo "Could not install dotnet from apt. Attempting to install dotnet from releases url" echo "Attempting to install dotnet from releases url"
fi fi
install_using_dotnet_releases_url "${DOTNET_SDK_OR_RUNTIME}" "${DOTNET_VERSION}" install_using_dotnet_releases_url "${DOTNET_SDK_OR_RUNTIME}" "${DOTNET_VERSION}"
CHANGE_OWNERSHIP="true" CHANGE_OWNERSHIP="true"

View file

@ -3,14 +3,14 @@
# Copyright (c) Microsoft Corporation. All rights reserved. # Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#------------------------------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/hugo.md
# Maintainer: The VS Code and Codespaces Teams
USERNAME=${USERNAME:-"automatic"} USERNAME=${USERNAME:-"automatic"}
UPDATE_RC=${UPDATE_RC:-"true"} UPDATE_RC=${UPDATE_RC:-"true"}
set -eux MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
set -eu
if [ "$(id -u)" -ne 0 ]; then if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
@ -66,72 +66,89 @@ apt_get_update_if_needed()
check_packages() { check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed apt_get_update_if_needed
DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends "$@" apt-get -y install --no-install-recommends "$@"
fi fi
} }
install_dotnet_using_apt() { install_dotnet_using_apt() {
wget --no-check-certificate https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb echo "Attempting to auto-install dotnet..."
sudo dpkg -i packages-microsoft-prod.deb install_from_microsoft_feed=false
rm packages-microsoft-prod.deb apt_get_update_if_needed
apt-get -yq install dotnet6 || install_from_microsoft_feed="true"
rm -rf /var/lib/apt/lists/* if [ "${install_from_microsoft_feed}" = "true" ]; then
check_packages apt-transport-https dotnet-sdk-6.0 echo "Attempting install from microsoft apt feed..."
curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list
apt-get update -y
DOTNET_SKIP_FIRST_TIME_EXPERIENCE="true" apt-get install -yq dotnet-sdk-6.0
fi
echo -e "Finished attempt to install dotnet. Sdks installed:\n"
dotnet --list-sdks
} }
# Install dependencies
check_packages git sudo wget ca-certificates
# If we don't already have Oryx installed, install it now. # If we don't already have Oryx installed, install it now.
if ! oryx --version > /dev/null ; then if oryx --version > /dev/null ; then
echo "Installing Oryx..." echo "oryx is already installed. Skipping installation."
exit 0
fi
if ! cat /etc/group | grep -e "^oryx:" > /dev/null 2>&1; then echo "Installing Oryx..."
# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive
. /etc/os-release
architecture="$(dpkg --print-architecture)"
# Install dependencies
check_packages git sudo curl ca-certificates apt-transport-https gnupg2 dirmngr libc-bin
if ! cat /etc/group | grep -e "^oryx:" > /dev/null 2>&1; then
groupadd -r oryx groupadd -r oryx
fi fi
usermod -a -G oryx "${USERNAME}" usermod -a -G oryx "${USERNAME}"
# Install dotnet unless available # Install dotnet unless available
if ! dotnet --version > /dev/null ; then if ! dotnet --version > /dev/null ; then
echo "'dotnet' was not detected. Attempting to install the latest version of the dotnet sdk to build oryx." echo "'dotnet' was not detected. Attempting to install the latest version of the dotnet sdk to build oryx."
install_dotnet_using_apt install_dotnet_using_apt
if ! dotnet --version > /dev/null ; then if ! dotnet --version > /dev/null ; then
echo "Please install Dotnet before installing Oryx" echo "(!) Please install Dotnet before installing Oryx"
exit 1 exit 1
fi fi
fi
BUILD_SCRIPT_GENERATOR=/usr/local/buildscriptgen
ORYX=/usr/local/oryx
GIT_ORYX=/opt/tmp
mkdir -p ${BUILD_SCRIPT_GENERATOR}
mkdir -p ${ORYX}
git clone --depth=1 https://github.com/microsoft/Oryx $GIT_ORYX
$GIT_ORYX/build/buildSln.sh
dotnet publish -property:ValidateExecutableReferencesMatchSelfContained=false -r linux-x64 -o ${BUILD_SCRIPT_GENERATOR} -c Release $GIT_ORYX/src/BuildScriptGeneratorCli/BuildScriptGeneratorCli.csproj
dotnet publish -r linux-x64 -o ${BUILD_SCRIPT_GENERATOR} -c Release $GIT_ORYX/src/BuildServer/BuildServer.csproj
chmod a+x ${BUILD_SCRIPT_GENERATOR}/GenerateBuildScript
ln -s ${BUILD_SCRIPT_GENERATOR}/GenerateBuildScript ${ORYX}/oryx
cp -f $GIT_ORYX/images/build/benv.sh ${ORYX}/benv
ORYX_INSTALL_DIR="/opt"
mkdir -p "${ORYX_INSTALL_DIR}"
updaterc "export ORYX_SDK_STORAGE_BASE_URL=https://oryx-cdn.microsoft.io && export ENABLE_DYNAMIC_INSTALL=true && DYNAMIC_INSTALL_ROOT_DIR=$ORYX_INSTALL_DIR && ORYX_PREFER_USER_INSTALLED_SDKS=true && export DEBIAN_FLAVOR=focal-scm"
chown -R "${USERNAME}:oryx" "${ORYX_INSTALL_DIR}" "${BUILD_SCRIPT_GENERATOR}" "${ORYX}"
chmod -R g+r+w "${ORYX_INSTALL_DIR}" "${BUILD_SCRIPT_GENERATOR}" "${ORYX}"
find "${ORYX_INSTALL_DIR}" -type d | xargs -n 1 chmod g+s
find "${BUILD_SCRIPT_GENERATOR}" -type d | xargs -n 1 chmod g+s
find "${ORYX}" -type d | xargs -n 1 chmod g+s
fi fi
BUILD_SCRIPT_GENERATOR=/usr/local/buildscriptgen
ORYX=/usr/local/oryx
GIT_ORYX=/opt/tmp
mkdir -p ${BUILD_SCRIPT_GENERATOR}
mkdir -p ${ORYX}
git clone --depth=1 https://github.com/microsoft/Oryx $GIT_ORYX
$GIT_ORYX/build/buildSln.sh
dotnet publish -property:ValidateExecutableReferencesMatchSelfContained=false -r linux-x64 -o ${BUILD_SCRIPT_GENERATOR} -c Release $GIT_ORYX/src/BuildScriptGeneratorCli/BuildScriptGeneratorCli.csproj
dotnet publish -r linux-x64 -o ${BUILD_SCRIPT_GENERATOR} -c Release $GIT_ORYX/src/BuildServer/BuildServer.csproj
chmod a+x ${BUILD_SCRIPT_GENERATOR}/GenerateBuildScript
ln -s ${BUILD_SCRIPT_GENERATOR}/GenerateBuildScript ${ORYX}/oryx
cp -f $GIT_ORYX/images/build/benv.sh ${ORYX}/benv
ORYX_INSTALL_DIR="/opt"
mkdir -p "${ORYX_INSTALL_DIR}"
updaterc "export ORYX_SDK_STORAGE_BASE_URL=https://oryx-cdn.microsoft.io && export ENABLE_DYNAMIC_INSTALL=true && DYNAMIC_INSTALL_ROOT_DIR=$ORYX_INSTALL_DIR && ORYX_PREFER_USER_INSTALLED_SDKS=true && export DEBIAN_FLAVOR=focal-scm"
chown -R "${USERNAME}:oryx" "${ORYX_INSTALL_DIR}" "${BUILD_SCRIPT_GENERATOR}" "${ORYX}"
chmod -R g+r+w "${ORYX_INSTALL_DIR}" "${BUILD_SCRIPT_GENERATOR}" "${ORYX}"
find "${ORYX_INSTALL_DIR}" -type d | xargs -n 1 chmod g+s
find "${BUILD_SCRIPT_GENERATOR}" -type d | xargs -n 1 chmod g+s
find "${ORYX}" -type d | xargs -n 1 chmod g+s
echo "Done!" echo "Done!"

View file

@ -0,0 +1,13 @@
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
check "dotnet sdks" dotnet --list-sdks
check "some major version of dotnet 3 is installed" dotnet --list-sdks | grep '3\.[0-9]*\.[0-9]*'
check "dotnet version 3 installed" ls -l /usr/share/dotnet/sdk | grep '3\.[0-9]*\.[0-9]*'
# Report result
reportResults

View file

@ -0,0 +1,14 @@
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
check "dotnet sdks" dotnet --list-sdks
check "some major version of dotnet 5 is installed" dotnet --list-sdks | grep '5\.[0-9]*\.[0-9]*'
check "dotnet version 5 installed" ls -l /usr/share/dotnet/sdk | grep '5\.[0-9]*\.[0-9]*'
# Report result
reportResults

View file

@ -75,5 +75,21 @@
"additionalVersions": "5.0,3.1.420" "additionalVersions": "5.0,3.1.420"
} }
} }
},
"install_dotnet_5": {
"image": "ubuntu:focal",
"features": {
"dotnet": {
"version": "5"
}
}
},
"install_dotnet_3": {
"image": "ubuntu:focal",
"features": {
"dotnet": {
"version": "3"
}
}
} }
} }

View file

@ -9,5 +9,8 @@ source dev-container-features-test-lib
check "dotnet" dotnet --info check "dotnet" dotnet --info
check "sdks" dotnet --list-sdks check "sdks" dotnet --list-sdks
echo "Validating expected version present..."
check "some major version of dotnet 6 is installed" dotnet --list-sdks | grep '6\.[0-9]*\.[0-9]*'
# Report result # Report result
reportResults reportResults