diff --git a/.github/actions/build-and-test-feature/action.yml b/.github/actions/build-and-test-feature/action.yml index 896ffcc66..317cb1868 100644 --- a/.github/actions/build-and-test-feature/action.yml +++ b/.github/actions/build-and-test-feature/action.yml @@ -4,6 +4,7 @@ description: Test feature inputs: args: {type: string, required: true} + scenario: {type: string, required: false} gh_token: {type: string, defaut: '', required: false} aws_idp_url: {type: string, defaut: '', required: false} aws_role_arn: {type: string, defaut: '', required: false} @@ -26,11 +27,12 @@ runs: - name: Test feature shell: bash run: | - devcontainer features test $ARGS ./features; + devcontainer features test --project-folder ./features $ARGS ${SCENARIO:+--filter "$SCENARIO"} env: NODE_NO_WARNINGS: 1 VAULT_S3_TTL: "900" # 15 minutes ARGS: ${{ inputs.args }} + SCENARIO: "${{ inputs.scenario }}" gh_token: "${{ inputs.gh_token }}" aws_idp_url: "${{ inputs.aws_idp_url }}" aws_role_arn: "${{ inputs.aws_role_arn }}" diff --git a/.github/actions/feature-matrix/action.sh b/.github/actions/feature-matrix/action.sh index a819d49b9..d598192db 100755 --- a/.github/actions/feature-matrix/action.sh +++ b/.github/actions/feature-matrix/action.sh @@ -8,9 +8,9 @@ join_with_delimiter() { } find_features_with_tests() { - find ${@:2} -mindepth 1 -type f -name "$1" ! -wholename '*/test/_global/*' \ - -exec bash -c 'echo {} | sed -r s@features/test/\(.*\)/.*@\\1@' \; \ - | sort | uniq ; + find "${@:2}" -mindepth 1 -type f -name "$1" ! -wholename '*/test/_global/*' \ + -exec bash -c 'echo {} | sed -r s@features/test/\(.*\)/.*@\\1@' \; \ + | sort | uniq ; } full_matrix="0"; @@ -22,35 +22,40 @@ esac files="${@}"; -features=""; -scenarios=""; +declare -a features=(); +declare -a scenarios=(); if [ "${full_matrix}" == "1" ] || grep -q "\.github/" <<< "$files"; then - features="$(find_features_with_tests 'test.sh' 'features/test')"; - scenarios="$(find_features_with_tests 'scenarios.json' 'features/test')"; + declare -a features="($(find_features_with_tests 'test.sh' 'features/test'))" + declare -a scenarios="($(find_features_with_tests 'scenarios.json' 'features/test'))" elif echo "$files" | grep -q "features/"; then - files="$(join_with_delimiter "\n" $files | grep "features/")"; - files="$(echo -e "$files")"; + files="$(join_with_delimiter "\n" $files | grep "features/")" + declare -a files="($(echo -e "$files"))" changed=(); - for x in ${files}; do + for x in "${files[@]}"; do x="${x##features/src/}"; x="${x##features/test/}"; x="features/test/${x%%/*}"; changed+=("${x}"); - done; - changed="${changed[@]}"; - features="$(find_features_with_tests 'test.sh' ${changed})"; - scenarios="$(find_features_with_tests 'scenarios.json' ${changed})"; + done + declare -a features="($(find_features_with_tests 'test.sh' "${changed[@]}"))" + declare -a scenarios="($(find_features_with_tests 'scenarios.json' "${changed[@]}"))" fi -if [[ -n "$(echo "$features")" ]]; then - features="[\"$(join_with_delimiter '","' $features)\"]"; +if test "${#features[@]}" -gt 0; then + features="[\"$(join_with_delimiter '","' "${features[@]}")\"]"; fi echo "features=${features:-[]}"; -if [[ -n "$(echo "$scenarios")" ]]; then - scenarios="[\"$(join_with_delimiter '","' $scenarios)\"]"; +if test "${#scenarios[@]}" -gt 0; then + declare -a scenarios_json=() + for feature in "${scenarios[@]}"; do + if test -f "features/test/$feature/scenarios.json"; then + scenarios_json+=("{\"feature\": \"$feature\", \"scenarios\": $(jq -cM "keys | @json" "features/test/$feature/scenarios.json" | tr -d '\n')}") + fi + done + scenarios="[$(IFS=,; echo "${scenarios_json[*]}")]"; fi echo "scenarios=${scenarios:-[]}"; diff --git a/.github/actions/image-matrix/action.yml b/.github/actions/image-matrix/action.yml index c5e64a2ba..05f54214e 100644 --- a/.github/actions/image-matrix/action.yml +++ b/.github/actions/image-matrix/action.yml @@ -59,6 +59,6 @@ runs: .github/actions/image-matrix/action.sh \ "$FULL_MATRIX" \ "$FEATURES" \ - "$SCENARIOS" \ + "$(jq 'map(.feature)' <<< "$SCENARIOS")" \ "$CHANGED_FILES" \ | tee -a $GITHUB_OUTPUT; diff --git a/.github/workflows/build-and-test-feature.yml b/.github/workflows/build-and-test-feature.yml index 9abfb46be..2e71125da 100644 --- a/.github/workflows/build-and-test-feature.yml +++ b/.github/workflows/build-and-test-feature.yml @@ -10,19 +10,24 @@ on: args: type: string required: true + scenarios: + type: string + default: '[""]' + required: false jobs: test: - name: ${{ format(inputs.name, matrix.arch) }} + name: ${{ format(inputs.name, matrix.arch, matrix.scenario || '') }} runs-on: ${{ fromJSON(github.repository != 'rapidsai/devcontainers' && '"ubuntu-latest"' || format('"linux-{0}-cpu4"', matrix.arch)) }} strategy: fail-fast: false matrix: arch: [amd64, arm64] + scenario: ${{ fromJSON(inputs.scenarios || '[""]') }} steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false @@ -36,9 +41,10 @@ jobs: uses: ./.github/actions/build-and-test-feature with: args: "${{ inputs.args }}" + scenario: "${{ matrix.scenario }}" gh_token: "${{ secrets.GIST_REPO_READ_ORG_GITHUB_TOKEN }}" aws_idp_url: ${{ secrets.GIST_REPO_READ_ORG_GITHUB_TOKEN && 'https://token.rapids.nvidia.com' || '' }} aws_role_arn: "${{ secrets.GIST_REPO_READ_ORG_GITHUB_TOKEN && 'arn:aws:iam::279114543810:role/rapids-token-sccache-devs' || '' }}" rw_sccache_bucket: "${{ secrets.GIST_REPO_READ_ORG_GITHUB_TOKEN && 'rapids-sccache-devs' || '' }}" rw_sccache_region: "${{ vars.AWS_REGION }}" - sccache_dist_scheduler_url: "sccache.rapids.nvidia.com" + sccache_dist_scheduler_url: "https://sccache.rapids.nvidia.com" diff --git a/.github/workflows/build-test-and-push-linux-image.yml b/.github/workflows/build-test-and-push-linux-image.yml index 6216d1171..c8ffd134c 100644 --- a/.github/workflows/build-test-and-push-linux-image.yml +++ b/.github/workflows/build-test-and-push-linux-image.yml @@ -41,7 +41,7 @@ jobs: version: ${{ steps.json.outputs.version }} steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/build-test-and-push-windows-image.yml b/.github/workflows/build-test-and-push-windows-image.yml index 4ad09786a..368016d38 100644 --- a/.github/workflows/build-test-and-push-windows-image.yml +++ b/.github/workflows/build-test-and-push-windows-image.yml @@ -37,7 +37,7 @@ jobs: - { edition: "2022", runner: "${{ github.repository != 'rapidsai/devcontainers' && 'windows-2022' || 'windows-amd64-cpu4' }}" } steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a9293d58b..78bee3f48 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -20,9 +20,9 @@ jobs: pull-requests: write steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - persist-credentials: false + persist-credentials: true - name: Copy common scripts into features uses: ./.github/actions/copy-common-scripts diff --git a/.github/workflows/release-features.yml b/.github/workflows/release-features.yml index ab874ab29..bdde10e7c 100644 --- a/.github/workflows/release-features.yml +++ b/.github/workflows/release-features.yml @@ -13,7 +13,7 @@ jobs: packages: write steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index 79623f452..daf0c4a32 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -21,7 +21,7 @@ jobs: scenarios: "${{ steps.matrix.outputs.scenarios }}" steps: - name: "Checkout ${{ github.repository }}" - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false @@ -45,7 +45,7 @@ jobs: linux: ${{ steps.matrix.outputs.linux }} steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index f2cd3c63e..53fa85bb2 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -20,7 +20,7 @@ jobs: windows: ${{ steps.matrix.outputs.windows }} steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 793d4bae6..6723a970c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,7 +46,7 @@ jobs: scenarios: "${{ steps.matrix.outputs.scenarios }}" steps: - name: "Checkout ${{ github.repository }}" - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false @@ -71,7 +71,7 @@ jobs: windows: ${{ steps.matrix.outputs.windows }} steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1f8957dfb..2750c9a68 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false @@ -65,7 +65,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false @@ -90,7 +90,7 @@ jobs: scenarios: ${{ steps.matrix.outputs.scenarios }} steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false @@ -138,10 +138,11 @@ jobs: strategy: fail-fast: false matrix: - feature: ${{ fromJSON(needs.features-matrix.outputs.scenarios) }} + include: ${{ fromJSON(needs.features-matrix.outputs.scenarios) }} with: - name: "{0}" - args: "-f ${{ matrix.feature }} --skip-autogenerated" + name: "{1} ({0})" + scenarios: "${{ matrix.scenarios }}" + args: "-f ${{ matrix.feature }} --skip-autogenerated --skip-duplicated" run-generated-feature-tests: if: needs.features-matrix.outputs.features != '[]' @@ -157,7 +158,7 @@ jobs: feature: ${{ fromJSON(needs.features-matrix.outputs.features) }} with: name: "{0}" - args: "-f ${{ matrix.feature }} -i ubuntu:24.04 --skip-scenarios" + args: "-f ${{ matrix.feature }} -i ubuntu:24.04 --skip-scenarios --skip-duplicated" image-matrix: name: Determine image matrix @@ -171,7 +172,7 @@ jobs: windows: ${{ steps.matrix.outputs.windows }} steps: - name: Checkout ${{ github.repository }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false diff --git a/features/src/cccl-dev/devcontainer-feature.json b/features/src/cccl-dev/devcontainer-feature.json index a47c0f80c..1b030aa90 100644 --- a/features/src/cccl-dev/devcontainer-feature.json +++ b/features/src/cccl-dev/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "NVIDIA CCCL development utilities", "id": "cccl-dev", - "version": "26.8.0", + "version": "26.8.1", "description": "A feature to install NVIDIA CCCL development utilities", "options": { "litVersion": { diff --git a/features/src/cccl-dev/install.sh b/features/src/cccl-dev/install.sh index e0442d325..086fca7db 100644 --- a/features/src/cccl-dev/install.sh +++ b/features/src/cccl-dev/install.sh @@ -32,7 +32,7 @@ PKG=("gettext-base" "libtbb-dev" "pbzip2" "zstd" "wget"); PKG_TO_REMOVE=(); # Install gcc and g++ because we have to build psutil wheel for non-x86 -if [[ "$(uname -p)" != "x86_64" ]]; then +if [[ "$(uname -m)" != "x86_64" ]]; then if ! command -V gcc >/dev/null 2>&1; then PKG_TO_REMOVE+=("gcc"); fi if ! command -V g++ >/dev/null 2>&1; then PKG_TO_REMOVE+=("g++"); fi fi diff --git a/features/src/cuda/devcontainer-feature.json b/features/src/cuda/devcontainer-feature.json index 343358784..ea821c74e 100644 --- a/features/src/cuda/devcontainer-feature.json +++ b/features/src/cuda/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "CUDA Toolkit", "id": "cuda", - "version": "26.8.1", + "version": "26.8.2", "description": "A feature to install the NVIDIA CUDA Toolkit", "options": { "version": { diff --git a/features/src/cuda/install.sh b/features/src/cuda/install.sh index aaf36c7ba..204048411 100644 --- a/features/src/cuda/install.sh +++ b/features/src/cuda/install.sh @@ -22,7 +22,7 @@ check_packages \ echo "Downloading CUDA keyring..."; -export NVARCH="$(uname -p)"; +export NVARCH="$(uname -m)"; export OSNAME="$( . /etc/os-release; major="$(cut -d'.' -f1 <<< "${VERSION_ID}")"; @@ -30,6 +30,13 @@ export OSNAME="$( echo "$ID$((major - (major % 2)))${minor}"; )"; +export OSNAME_PREV="$( + . /etc/os-release; + major="$(cut -d'.' -f1 <<< "${VERSION_ID}")"; + minor="$(cut -d'.' -f2 <<< "${VERSION_ID}")"; + echo "$ID$((major - (major % 2) - 2))${minor}"; +)"; + VERSION="${CUDA_VERSION:-${VERSION:-13.3.0}}"; if [[ "$NVARCH" == aarch64 ]]; then @@ -200,22 +207,32 @@ if [ "${INSTALLNCCL:-false}" = true ] \ fi if [ "${INSTALLCUTENSOR:-false}" = true ]; then - # HACK: libcutensor-dev isn't currently in the ubuntu22.04 repo, - # but is in ubuntu20.04. Detect this and download the 20.04 deb. - if ! dpkg -s libcutensor-dev > /dev/null 2>&1; then - # If `libcutensor-deb` is available in the apt repo, install it - if ! dpkg -p libcutensor-dev 2>&1 | grep -q "not available" >/dev/null 2>&1; then + # If `libcutensor-dev` is available in the apt repo, install it + if dpkg -p libcutensor-dev 2>&1 | grep -q "not available" >/dev/null 2>&1; then + # HACK: + # If libcutensor-dev isn't in the apt repo for the current OS + # version, download and install it from the prev version repo + CUTENSOR_DEBS=() + prev_cuda_repo="${cuda_repo_base}/${OSNAME_PREV}/${NVARCH}"; + CUTENSOR_DEBS+=($(get_cuda_deb "${prev_cuda_repo}" libcutensor1 2>/dev/null || :)); + CUTENSOR_DEBS+=($(get_cuda_deb "${prev_cuda_repo}" libcutensor2 2>/dev/null || :)); + if test "${#CUTENSOR_DEBS[@]}" -eq 0 || [ "${INSTALLDEVPACKAGES:-false}" = true ]; then + CUTENSOR_DEBS+=($(get_cuda_deb "${prev_cuda_repo}" libcutensor-dev 2>/dev/null || :)); + fi + if test "${#CUTENSOR_DEBS[@]}" -eq 0; then + echo "Error: No matching .deb found for libcutensor or libcutensor-dev" >&2 + exit 1; + fi + PKGS+=("${CUTENSOR_DEBS[@]}") + else + if dpkg -s libcutensor1 >/dev/null 2>&1; then PKGS+=("libcutensor1"); - if [ "${INSTALLDEVPACKAGES:-false}" = true ]; then - PKGS+=("libcutensor-dev"); - fi - else - # If it's not in the apt repo for the current OS version, install it from the 20.04 repo - focal_cuda_repo="${cuda_repo_base}/ubuntu2004/${NVARCH}"; - PKGS+=("$(get_cuda_deb "${focal_cuda_repo}" libcutensor1)"); - if [ "${INSTALLDEVPACKAGES:-false}" = true ]; then - PKGS+=("$(get_cuda_deb "${focal_cuda_repo}" libcutensor-dev)"); - fi + fi + if dpkg -s libcutensor2 >/dev/null 2>&1; then + PKGS+=("libcutensor2"); + fi + if [ "${INSTALLDEVPACKAGES:-false}" = true ]; then + PKGS+=("libcutensor-dev"); fi fi fi diff --git a/features/src/cuda/prune-extra-cutensor-libs.sh b/features/src/cuda/prune-extra-cutensor-libs.sh index 67a4ab7ab..180d34dad 100755 --- a/features/src/cuda/prune-extra-cutensor-libs.sh +++ b/features/src/cuda/prune-extra-cutensor-libs.sh @@ -1,50 +1,55 @@ # Remove extra libcutensor versions -libcutensor_ver="$(dpkg -s libcutensor1 | grep '^Version:' | cut -d' ' -f2 | cut -d'-' -f1 | cut -d'.' -f4 --complement)"; -libcutensorMg_shared="$(find /usr/lib -type f -regex "^.*/libcutensor/${CUDA_VERSION_MAJOR}/libcutensorMg.so.${libcutensor_ver}$")"; - -if test -n "${libcutensorMg_shared:+x}"; then - - libcutensorMg_shared="$(find /usr/lib -type f -regex "^.*/libcutensor/${CUDA_VERSION_MAJOR}/libcutensorMg.so.${libcutensor_ver}$")"; - libcutensorMg_static="$(find /usr/lib -type f -regex "^.*/libcutensor/${CUDA_VERSION_MAJOR}/libcutensorMg_static.a$")"; - libcutensor_shared="$(find /usr/lib -type f -regex "^.*/libcutensor/${CUDA_VERSION_MAJOR}/libcutensor.so.${libcutensor_ver}$")"; - libcutensor_static="$(find /usr/lib -type f -regex "^.*/libcutensor/${CUDA_VERSION_MAJOR}/libcutensor_static.a$")"; - - libcutensorMg_shared_link="$(update-alternatives --query libcutensorMg.so.${libcutensor_ver} 2>/dev/null | grep '^Link:' | cut -d' ' -f2 || echo)"; - libcutensorMg_static_link="$(update-alternatives --query libcutensorMg_static.a 2>/dev/null | grep '^Link:' | cut -d' ' -f2 || echo)"; - libcutensor_shared_link="$(update-alternatives --query libcutensor.so.${libcutensor_ver} 2>/dev/null | grep '^Link:' | cut -d' ' -f2 || echo)"; - libcutensor_static_link="$(update-alternatives --query libcutensor_static.a 2>/dev/null | grep '^Link:' | cut -d' ' -f2 || echo)"; - - # 1. Remove existing libcutensor lib alternatives - # 2. Install only the alternative for the version we keep - # 3. Set the default alternatives - - if test -n "${libcutensorMg_shared:+x}" && test -f "${libcutensorMg_shared}" \ - && test -n "${libcutensorMg_shared_link:+x}" && test -L "${libcutensorMg_shared_link}"; then - (update-alternatives --remove-all libcutensorMg.so.${libcutensor_ver} >/dev/null 2>&1 || true); - update-alternatives --install "${libcutensorMg_shared_link}" libcutensorMg.so.${libcutensor_ver} "${libcutensorMg_shared}" 0; - update-alternatives --set libcutensorMg.so.${libcutensor_ver} "${libcutensorMg_shared}"; - fi - - if test -n "${libcutensorMg_static:+x}" && test -f "${libcutensorMg_static}" \ - && test -n "${libcutensorMg_static_link:+x}" && test -L "${libcutensorMg_static_link}"; then - (update-alternatives --remove-all libcutensorMg_static.a >/dev/null 2>&1 || true); - update-alternatives --install "${libcutensorMg_static_link}" libcutensorMg_static.a "${libcutensorMg_static}" 0; - update-alternatives --set libcutensorMg_static.a "${libcutensorMg_static}"; - fi - - if test -n "${libcutensor_shared:+x}" && test -f "${libcutensor_shared}" \ - && test -n "${libcutensor_shared_link:+x}" && test -L "${libcutensor_shared_link}"; then - (update-alternatives --remove-all libcutensor.so.${libcutensor_ver} >/dev/null 2>&1 || true); - update-alternatives --install "${libcutensor_shared_link}" libcutensor.so.${libcutensor_ver} "${libcutensor_shared}" 0; - update-alternatives --set libcutensor.so.${libcutensor_ver} "${libcutensor_shared}"; +for libcutensor_lib in libcutensor1 libcutensor2; do + if ! dpkg -s "$libcutensor_lib" >/dev/null 2>&1; then + continue; fi + libcutensor_ver="$(dpkg -s "$libcutensor_lib" | grep '^Version:' | cut -d' ' -f2 | cut -d'-' -f1 | cut -d'.' -f4 --complement)"; + libcutensorMg_shared="$(find /usr/lib -type f -regex "^.*/libcutensor/${CUDA_VERSION_MAJOR}/libcutensorMg.so.${libcutensor_ver}$")"; - if test -n "${libcutensor_static:+x}" && test -f "${libcutensor_static}" \ - && test -n "${libcutensor_static_link:+x}" && test -L "${libcutensor_static_link}"; then - (update-alternatives --remove-all libcutensor_static.a >/dev/null 2>&1 || true); - update-alternatives --install "${libcutensor_static_link}" libcutensor_static.a "${libcutensor_static}" 0; - update-alternatives --set libcutensor_static.a "${libcutensor_static}"; + if test -n "${libcutensorMg_shared:+x}"; then + + libcutensorMg_shared="$(find /usr/lib -type f -regex "^.*/libcutensor/${CUDA_VERSION_MAJOR}/libcutensorMg.so.${libcutensor_ver}$")"; + libcutensorMg_static="$(find /usr/lib -type f -regex "^.*/libcutensor/${CUDA_VERSION_MAJOR}/libcutensorMg_static.a$")"; + libcutensor_shared="$(find /usr/lib -type f -regex "^.*/libcutensor/${CUDA_VERSION_MAJOR}/libcutensor.so.${libcutensor_ver}$")"; + libcutensor_static="$(find /usr/lib -type f -regex "^.*/libcutensor/${CUDA_VERSION_MAJOR}/libcutensor_static.a$")"; + + libcutensorMg_shared_link="$(update-alternatives --query libcutensorMg.so.${libcutensor_ver} 2>/dev/null | grep '^Link:' | cut -d' ' -f2 || echo)"; + libcutensorMg_static_link="$(update-alternatives --query libcutensorMg_static.a 2>/dev/null | grep '^Link:' | cut -d' ' -f2 || echo)"; + libcutensor_shared_link="$(update-alternatives --query libcutensor.so.${libcutensor_ver} 2>/dev/null | grep '^Link:' | cut -d' ' -f2 || echo)"; + libcutensor_static_link="$(update-alternatives --query libcutensor_static.a 2>/dev/null | grep '^Link:' | cut -d' ' -f2 || echo)"; + + # 1. Remove existing libcutensor lib alternatives + # 2. Install only the alternative for the version we keep + # 3. Set the default alternatives + + if test -n "${libcutensorMg_shared:+x}" && test -f "${libcutensorMg_shared}" \ + && test -n "${libcutensorMg_shared_link:+x}" && test -L "${libcutensorMg_shared_link}"; then + (update-alternatives --remove-all libcutensorMg.so.${libcutensor_ver} >/dev/null 2>&1 || true); + update-alternatives --install "${libcutensorMg_shared_link}" libcutensorMg.so.${libcutensor_ver} "${libcutensorMg_shared}" 0; + update-alternatives --set libcutensorMg.so.${libcutensor_ver} "${libcutensorMg_shared}"; + fi + + if test -n "${libcutensorMg_static:+x}" && test -f "${libcutensorMg_static}" \ + && test -n "${libcutensorMg_static_link:+x}" && test -L "${libcutensorMg_static_link}"; then + (update-alternatives --remove-all libcutensorMg_static.a >/dev/null 2>&1 || true); + update-alternatives --install "${libcutensorMg_static_link}" libcutensorMg_static.a "${libcutensorMg_static}" 0; + update-alternatives --set libcutensorMg_static.a "${libcutensorMg_static}"; + fi + + if test -n "${libcutensor_shared:+x}" && test -f "${libcutensor_shared}" \ + && test -n "${libcutensor_shared_link:+x}" && test -L "${libcutensor_shared_link}"; then + (update-alternatives --remove-all libcutensor.so.${libcutensor_ver} >/dev/null 2>&1 || true); + update-alternatives --install "${libcutensor_shared_link}" libcutensor.so.${libcutensor_ver} "${libcutensor_shared}" 0; + update-alternatives --set libcutensor.so.${libcutensor_ver} "${libcutensor_shared}"; + fi + + if test -n "${libcutensor_static:+x}" && test -f "${libcutensor_static}" \ + && test -n "${libcutensor_static_link:+x}" && test -L "${libcutensor_static_link}"; then + (update-alternatives --remove-all libcutensor_static.a >/dev/null 2>&1 || true); + update-alternatives --install "${libcutensor_static_link}" libcutensor_static.a "${libcutensor_static}" 0; + update-alternatives --set libcutensor_static.a "${libcutensor_static}"; + fi fi -fi -rm -rf $(find /usr/lib -mindepth 1 -type d -regex "^.*/libcutensor/.*$" | grep -Ev "^.*/libcutensor/${CUDA_VERSION_MAJOR}$"); + rm -rf $(find /usr/lib -mindepth 1 -type d -regex "^.*/libcutensor/.*$" | grep -Ev "^.*/libcutensor/${CUDA_VERSION_MAJOR}$"); +done diff --git a/features/src/gcc/devcontainer-feature.json b/features/src/gcc/devcontainer-feature.json index 3d4539ac3..c77f0e3bd 100644 --- a/features/src/gcc/devcontainer-feature.json +++ b/features/src/gcc/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "GCC", "id": "gcc", - "version": "26.8.0", + "version": "26.8.1", "description": "A feature to install gcc", "options": { "version": { diff --git a/features/src/gcc/install.sh b/features/src/gcc/install.sh index 1e1d18106..66617b3d7 100755 --- a/features/src/gcc/install.sh +++ b/features/src/gcc/install.sh @@ -8,6 +8,7 @@ cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"; . ./common/install.sh; check_packages \ + curl \ gpg \ dirmngr \ gpg-agent \ @@ -24,8 +25,16 @@ GCC_VERSION_DEFAULT="$(gcc -dumpversion)"; GCC_VERSION="${VERSION:-${GCC_VERSION_DEFAULT}}"; if [[ "${GCC_VERSION}" != "${GCC_VERSION_DEFAULT}" ]]; then - apt-add-repository -y ppa:ubuntu-toolchain-r/test; - apt-add-repository -y ppa:ubuntu-toolchain-r/ppa; + curl -fsSL --compressed "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xC8EC952E2A0E1FBDC5090F6A2C277A0A352154E5" | gpg --dearmor --yes -o /etc/apt/trusted.gpg.d/ubuntu-toolchain-r.gpg + cat </etc/apt/sources.list.d/ubuntu-toolchain-r-test.list +deb [arch=$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/')] https://ppa.launchpadcontent.net/ubuntu-toolchain-r/test/ubuntu $(. /etc/os-release; echo ${VERSION_CODENAME}) main +deb-src [arch=$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/')] https://ppa.launchpadcontent.net/ubuntu-toolchain-r/test/ubuntu $(. /etc/os-release; echo ${VERSION_CODENAME}) main +EOF + cat </etc/apt/sources.list.d/ubuntu-toolchain-r-ppa.list +deb [arch=$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/')] https://ppa.launchpadcontent.net/ubuntu-toolchain-r/ppa/ubuntu $(. /etc/os-release; echo ${VERSION_CODENAME}) main +deb-src [arch=$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/')] https://ppa.launchpadcontent.net/ubuntu-toolchain-r/ppa/ubuntu $(. /etc/os-release; echo ${VERSION_CODENAME}) main +EOF + apt update # Install gcc-${GCC_VERSION} DEBIAN_FRONTEND=noninteractive \ apt-get install -y --no-install-recommends \ diff --git a/features/src/git/NOTES.md b/features/src/git/NOTES.md new file mode 100644 index 000000000..507ba8e8b --- /dev/null +++ b/features/src/git/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Alpine, Debian/Ubuntu, RedHat Enterprise Linux, Fedora, Alma, and RockyLinux distributions with the `apk`, `apt`, `yum`, `dnf`, or `microdnf` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/features/src/git/README.md b/features/src/git/README.md new file mode 100644 index 000000000..e750bbed2 --- /dev/null +++ b/features/src/git/README.md @@ -0,0 +1,32 @@ + +# Git (from source) (git) + +Install an up-to-date version of Git, built from source as needed. Useful for when you want the latest and greatest features. Auto-detects latest stable version and installs needed dependencies. + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers/features/git:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Select or enter a Git version. | string | os-provided | +| ppa | Install from PPA if available (only supported for Ubuntu distributions) | boolean | true | + + + +## OS Support + +This Feature should work on recent versions of Alpine, Debian/Ubuntu, RedHat Enterprise Linux, Fedora, Alma, and RockyLinux distributions with the `apk`, `apt`, `yum`, `dnf`, or `microdnf` package manager installed. + +`bash` is required to execute the `install.sh` script. + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/git/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/features/src/git/common/etc/bash.bash_env b/features/src/git/common/etc/bash.bash_env new file mode 100755 index 000000000..0005efebc --- /dev/null +++ b/features/src/git/common/etc/bash.bash_env @@ -0,0 +1,37 @@ +#! /usr/bin/env bash + +# Respect --noprofile and --norc +if [[ ! $(ps -o args= -p $$) =~ (--noprofile) ]]; then + # Otherwise, initialize non-login shells like login shells + if ! shopt -q login_shell; then + if [ -f /etc/profile ]; then + . /etc/profile + fi + for x in "$HOME"/.{bash_profile,bash_login,profile}; do + if [ -f "$x" ]; then + . "$x" + break + fi + done + fi +elif [[ ! $(ps -o args= -p $$) =~ (--norc|--rcfile|--init-file) ]]; then + if [ -f /etc/bash.bashrc ]; then + . /etc/bash.bashrc + fi + for x in "$HOME"/.bashrc; do + if [ -f "$x" ]; then + . "$x" + break + fi + done +fi + +export BASH_ENV=/etc/bash.bash_env + +if [ -n "${BASH_ENV_ETC_PROFILE:-}" ]; then + if [ -f "$BASH_ENV_ETC_PROFILE" ] \ + && [ "$BASH_ENV_ETC_PROFILE" != "$BASH_ENV" ]; \ + then + . "$BASH_ENV_ETC_PROFILE" + fi +fi diff --git a/features/src/git/common/etc/skel/.config/clangd/config.yaml b/features/src/git/common/etc/skel/.config/clangd/config.yaml new file mode 100644 index 000000000..52c36cb9d --- /dev/null +++ b/features/src/git/common/etc/skel/.config/clangd/config.yaml @@ -0,0 +1,63 @@ +# https://clangd.llvm.org/config + +# Apply a config conditionally to all C files +If: + PathMatch: .*\.(c|h)$ + +--- + +# Apply a config conditionally to all C++ files +If: + PathMatch: .*\.(c|h)pp + +--- + +# Apply a config conditionally to all CUDA files +If: + PathMatch: .*\.cuh? +CompileFlags: + Add: + - "-x" + - "cuda" + # No error on unknown CUDA versions + - "-Wno-unknown-cuda-version" + # Allow variadic CUDA functions + - "-Xclang=-fcuda-allow-variadic-functions" + +--- + +# Tweak the clangd parse settings for all files +CompileFlags: + Add: + # report all errors + - "-ferror-limit=0" + - "-fmacro-backtrace-limit=0" + - "-ftemplate-backtrace-limit=0" + # Skip the CUDA version check + - "--no-cuda-version-check" + Remove: + # remove gcc's -fcoroutines + - -fcoroutines + # remove nvc++ flags unknown to clang + - "-gpu=*" + - "-stdpar*" + # remove nvcc flags unknown to clang + - "-arch*" + - "-gencode*" + - "--generate-code*" + - "-ccbin*" + - "-t=*" + - "--threads*" + - "-Xptxas*" + - "-Xcudafe*" + - "-Xfatbin*" + - "-Xcompiler*" + - "--diag-suppress*" + - "--diag_suppress*" + - "--compiler-options*" + - "--expt-extended-lambda" + - "--expt-relaxed-constexpr" + - "-forward-unknown-to-host-compiler" + - "-Werror=cross-execution-space-call" + - "--compress-mode*" + - "-static-global-template-stub*" diff --git a/features/src/git/common/find-version-from-git-tags.sh b/features/src/git/common/find-version-from-git-tags.sh new file mode 100755 index 000000000..b959c1310 --- /dev/null +++ b/features/src/git/common/find-version-from-git-tags.sh @@ -0,0 +1,129 @@ +#! /usr/bin/env bash + +# Assign variable one scope above the caller +# Usage: local "$1" && _upvar $1 "value(s)" +# Param: $1 Variable name to assign value to +# Param: $* Value(s) to assign. If multiple values, an array is +# assigned, otherwise a single value is assigned. +# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference +_upvar() { + if unset -v "$1"; then + if (( $# == 2 )); then + eval $1=\"\$2\"; + else + eval $1=\(\"\${@:2}\"\); + fi; + fi +} + +declare -Ag _find_version_from_git_tags_cache=(); + +# Figure out correct version of a three part version number is not passed +_find_version_from_git_tags() { + local variable_name="$1" + local requested_version="${!variable_name}" + if [ "${requested_version}" = "none" ]; then return; fi + local repository="$2" + local prefix="${3:-"tags/v"}" + local separator="${4:-"."}" + local suffix="${5:-}" + local last_part_optional="${6:-"false"}" + local after_version="${7:-""}" + if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then + local escaped_separator="${separator//./\\.}" + local last_part="" + if [ "${last_part_optional}" = "true" ]; then + last_part+="(${escaped_separator}[0-9]+)?" + last_part+="(${escaped_separator}[0-9]+)?" + if [ -n "${suffix:+x}" ]; then + last_part+="(${suffix})?" + fi + else + last_part+="${escaped_separator}[0-9]+" + last_part+="${escaped_separator}[0-9]+" + if [ -n "${suffix:+x}" ]; then + last_part+="(${suffix})" + fi + fi + local regex="${prefix}\\K[0-9]+${last_part}$" + + if ! test -v _find_version_from_git_tags_cache["$variable_name"]; then + local remote_upstream_fetch="$(git --no-pager config get remote.upstream.fetch)" + if test -n "${remote_upstream_fetch:+x}"; then + git config unset --global remote.upstream.fetch || true + fi + readarray -t version_list < <( + git ls-remote --tags "${repository}" \ + | grep -oP "${regex}" \ + | tr -d ' ' \ + | tr "${separator}" "." \ + | sort -rV + ) + if test -n "${remote_upstream_fetch:+x}"; then + git config set --global remote.upstream.fetch "${remote_upstream_fetch}" + fi + _upvar _find_version_from_git_tags_cache["$variable_name"] "${version_list[*]}" + else + readarray -d' ' -t version_list <<< "${_find_version_from_git_tags_cache["$variable_name"]}" + fi + local version_list="$(IFS=$'\n'; echo "${version_list[*]}")" + if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then + requested_version="$(head -n 1 <<< "${version_list}")" + elif test -n "${after_version:+x}"; then + set +e + requested_version="$(grep -A 1 -m 1 "${after_version}" <<< "${version_list}" | tail -n 1)" + set -e + else + set +e + requested_version="$(grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)" <<< "${version_list}")" + set -e + fi + fi + if [ ! -n "${requested_version:+x}" ] || ! grep "^${requested_version//./\\.}$" <<< "${version_list}" > /dev/null 2>&1; then + echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 + return 1 + fi + _upvar "${variable_name}" "${requested_version}" + echo "${variable_name}=${requested_version}" +} + +# Use semver logic to decrement a version number then look for the closest match +_find_prev_version_from_git_tags() { + local variable_name="$1" + local current_version="${!variable_name}" + local repository="$2" + # Normally a "v" is used before the version number, but support alternate cases + local prefix="${3:-"tags/v"}" + # Some repositories use "_" instead of "." for version number part separation, support that + local separator="${4:-"."}" + # Some repositories may have tags that include a suffix (e.g. actions/node-versions) + local version_suffix_regex="${5:-}" + # Some tools release versions that omit the last digit (e.g. go) + local last_part_optional="${6:-"false"}" + # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios. + set +e + local major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')" + local minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')" + local breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')" + + if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then + ((major=major-1)) + _upvar "${variable_name}" "${major}" + # Look for latest version from previous major release + _find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${version_suffix_regex}" "${last_part_optional}" + # Handle situations like Go's odd version pattern where "0" releases omit the last part + elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then + ((minor=minor-1)) + _upvar "${variable_name}" "${major}.${minor}" + # Look for latest version from previous minor release + _find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${version_suffix_regex}" "${last_part_optional}" + else + ((breakfix=breakfix-1)) + if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then + _upvar "${variable_name}" "${major}.${minor}" + else + _upvar "${variable_name}" "${major}.${minor}.${breakfix}" + fi + fi + set -e +} diff --git a/features/src/git/common/install.sh b/features/src/git/common/install.sh new file mode 100755 index 000000000..62c7cf810 --- /dev/null +++ b/features/src/git/common/install.sh @@ -0,0 +1,64 @@ +#! /usr/bin/env bash +set -e + +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.' + exit 1 +fi + +src="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# export bash utility functions +# shellcheck disable=SC1091 +source "$src/utilities.sh"; + +rm -f /etc/profile.d/00-restore-env.sh; + +# install /etc/skel +cp -r "$src/etc/skel" /etc/; +# install /etc/bash.bash_env +cp "$src/etc/bash.bash_env" /etc/; +chown root:root /etc/bash.bash_env; +chmod u+rwx,g+rwx,o+rx /etc/bash.bash_env; + +unset src; + +# Store and reset BASH_ENV in /etc/profile so lmod doesn't steal it from us. +# Our `/etc/bash.bash_env` will source lmod's $BASH_ENV at the end. +append_to_etc_profile "$(cat <> /etc/environment; +fi + +# Remove unnecessary "$HOME/.local/bin" at the end of the path +# shellcheck disable=SC2016 +if grep -qxF 'if [[ "${PATH}" != *"$HOME/.local/bin"* ]]; then export PATH="${PATH}:$HOME/.local/bin"; fi' /etc/bash.bashrc; then + grep -vxF \ + 'if [[ "${PATH}" != *"$HOME/.local/bin"* ]]; then export PATH="${PATH}:$HOME/.local/bin"; fi' \ + /etc/bash.bashrc \ + > /etc/bash.bashrc.new \ + && mv /etc/bash.bashrc{.new,}; +fi + +cp /etc/skel/.profile /root/.profile; +echo 'mesg n 2> /dev/null || true' >> /root/.profile; + +for_each_user_profile "$(cat <<"EOF" +sed -i 's@if \[ -d "$HOME/bin" \]@if [ -n "${PATH##*"$HOME/bin"*}" ] \&\& [ -d "$HOME/bin" ]@' $0; +sed -i 's@if \[ -d "$HOME/.local/bin" \]@if [ -n "${PATH##*"$HOME/.local/bin"*}" ] \&\& [ -d "$HOME/.local/bin" ]@' $0; +EOF +)"; + +# Fix the devcontainers/features/common-utils __bash_prompt fn +# shellcheck disable=SC2016 +for_each_user_bashrc ' +if [[ "$(grep -qE "^__bash_prompt\(\) \{$" "$0"; echo $?)" == 0 ]]; then + sed -i "s/\${BRANCH}/\${BRANCH:-}/g" "$0"; + sed -i "s/\${GITHUB_USER}/\${GITHUB_USER:-}/g" "$0"; +fi +'; diff --git a/features/src/git/common/utilities.sh b/features/src/git/common/utilities.sh new file mode 100644 index 000000000..49a044b95 --- /dev/null +++ b/features/src/git/common/utilities.sh @@ -0,0 +1,186 @@ +#! /usr/bin/env bash + +# Define common shell functions + +# Assign variable one scope above the caller +# Usage: local "$1" && _upvar $1 "value(s)" +# Param: $1 Variable name to assign value to +# Param: $* Value(s) to assign. If multiple values, an array is +# assigned, otherwise a single value is assigned. +# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference +_upvar() { + if unset -v "$1"; then + if (( $# == 2 )); then + eval $1=\"\$2\"; + else + eval $1=\(\"\${@:2}\"\); + fi; + fi +} + +# Run apt update if apt lists aren't populated +apt_get_update() { + if [ "$(find /var/lib/apt/lists -mindepth 1 | head -n1 | wc -l)" = "0" ]; then + echo "Running apt-get update..."; + apt-get update -y; + fi +} + +export -f apt_get_update; + +# Checks if packages are installed and installs them if not +check_packages() { + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update; + echo "Installing packages: $*"; + DEBIAN_FRONTEND=noninteractive \ + apt-get -y install --no-install-recommends "$@"; + fi +} + +export -f check_packages; + +for_each_user_bashrc() { + # Update all bashrc files + # shellcheck disable=SC2086 + find / /etc /home ${_REMOTE_USER_HOME} ${_CONTAINER_USER_HOME} -maxdepth 2 -type f -name .bashrc \ + | sort | uniq | xargs -r -d'\n' -n1 bash -c "${@}"; +} + +export -f for_each_user_bashrc; + +for_each_user_profile() { + # Update all .profile files + # shellcheck disable=SC2086 + find / /etc /home ${_REMOTE_USER_HOME} ${_CONTAINER_USER_HOME} -maxdepth 2 -type f -name .profile \ + | sort | uniq | xargs -r -d'\n' -n1 bash -c "${@}"; +} + +export -f for_each_user_profile; + +append_to_all_bashrcs() { + # Update all bashrc files + # shellcheck disable=SC2086 + for bashrc in $(find / /etc /home ${_REMOTE_USER_HOME} ${_CONTAINER_USER_HOME} -maxdepth 2 -type f -name .bashrc | sort | uniq); do + if [[ "$(cat "$bashrc")" != *"$1"* ]]; then + echo "Appending to $bashrc..."; + echo -e "$1" >> "$bashrc"; + fi + done +} + +export -f append_to_all_bashrcs; + +prepend_to_all_bashrcs() { + # Update all bashrc files + # shellcheck disable=SC2086 + for bashrc in $(find / /etc /home ${_REMOTE_USER_HOME} ${_CONTAINER_USER_HOME} -maxdepth 2 -type f -name .bashrc | sort | uniq); do + if [[ "$(cat "$bashrc")" != *"$1"* ]]; then + echo "Prepending to $bashrc..."; + echo -e "$1\n$(cat "$bashrc")" > "$bashrc"; + fi + done +} + +export -f prepend_to_all_bashrcs; + +append_to_etc_profile() { + if [[ "$(cat /etc/profile)" != *"$1"* ]]; then + echo "Appending to /etc/profile..."; + echo -e "$1" >> /etc/profile; + fi +} + +export -f append_to_etc_profile; + +prepend_to_etc_profile() { + if [[ "$(cat /etc/profile)" != *"$1"* ]]; then + echo "Prepending to /etc/profile..."; + echo -e "$1\n$(cat /etc/profile)" > /etc/profile; + fi +} + +export -f prepend_to_etc_profile; + +append_to_etc_bashrc() { + if [[ "$(cat /etc/bash.bashrc)" != *"$1"* ]]; then + echo "Appending to /etc/bash.bashrc..."; + echo -e "$1" >> /etc/bash.bashrc; + fi +} + +export -f append_to_etc_bashrc; + +prepend_to_etc_bashrc() { + if [[ "$(cat /etc/bash.bashrc)" != *"$1"* ]]; then + echo "Prepending to /etc/bash.bashrc..."; + echo -e "$1\n$(cat /etc/bash.bashrc)" > /etc/bash.bashrc; + fi +} + +export -f prepend_to_etc_bashrc; + +append_etc_zshrc() { + if [ -f "/etc/zsh/zshrc" ] && [[ "$(cat /etc/zsh/zshrc)" != *"$1"* ]]; then + echo "Appending to /etc/zsh/zshrc..."; + echo -e "$1" >> /etc/zsh/zshrc; + fi +} + +export -f append_etc_zshrc; + +prepend_to_etc_zshrc() { + if [ -f "/etc/zsh/zshrc" ] && [[ "$(cat /etc/zsh/zshrc)" != *"$1"* ]]; then + echo "Prepending to /etc/zsh/zshrc..."; + echo -e "$1\n$(cat /etc/zsh/zshrc)" > /etc/zsh/zshrc; + fi +} + +export -f prepend_to_etc_zshrc; + +add_etc_profile_d_script() { + # shellcheck disable=SC2012 + local name="$(($(ls -1q /etc/profile.d/*.sh | wc -l) + 20))-${1}.sh"; + echo -e "#! /usr/bin/env bash\n${*:2}" > "/etc/profile.d/${name}"; + chmod +x "/etc/profile.d/${name}"; +} + +export -f add_etc_profile_d_script; + +# Determine the appropriate non-root user +find_non_root_user() { + USERNAME="${USERNAME:-"${_REMOTE_USER:-"auto"}"}"; + if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then + USERNAME="" + POSSIBLE_USERS=("vscode" "node" "codespace" "coder" "$(awk -v val=1001 -F ":" '$3==val{print $1}' /etc/passwd)") + for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do + if id -u "${CURRENT_USER}" > /dev/null 2>&1; then + USERNAME=${CURRENT_USER} + break + fi + done + elif [ "${USERNAME}" = "none" ] || ! id -u "${USERNAME}" > /dev/null 2>&1; then + USERNAME=root + fi + if [ "${USERNAME}" = "" ]; then + USERNAME=root + fi +} + +export -f find_non_root_user; + +# shellcheck disable=SC1091 +. "$(dirname "$(realpath -m "${BASH_SOURCE[0]}")")/find-version-from-git-tags.sh"; + +find_version_from_git_tags() { + check_packages git; + _find_version_from_git_tags "$@"; +} + +export -f find_version_from_git_tags; + +find_prev_version_from_git_tags() { + _find_prev_version_from_git_tags "$@"; +} + +export -f find_prev_version_from_git_tags; diff --git a/features/src/git/devcontainer-feature.json b/features/src/git/devcontainer-feature.json new file mode 100644 index 000000000..93ea7b061 --- /dev/null +++ b/features/src/git/devcontainer-feature.json @@ -0,0 +1,38 @@ +{ + "id": "git", + "version": "1.3.6", + "name": "Git (from source)", + "documentationURL": "https://github.com/devcontainers/features/tree/main/src/git", + "description": "Install an up-to-date version of Git, built from source as needed. Useful for when you want the latest and greatest features. Auto-detects latest stable version and installs needed dependencies.", + "options": { + "version": { + "type": "string", + "proposals": [ + "latest", + "system", + "os-provided" + ], + "default": "os-provided", + "description": "Select or enter a Git version." + }, + "ppa": { + "type": "boolean", + "default": true, + "description": "Install from PPA if available (only supported for Ubuntu distributions)" + } + }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes an up-to-date version of Git, built from source as needed, pre-installed and available on the `PATH`." + } + ] + } + } + }, + "installsAfter": [ + "ghcr.io/devcontainers/features/common-utils" + ] +} diff --git a/features/src/git/install.sh b/features/src/git/install.sh new file mode 100644 index 000000000..f4919eb63 --- /dev/null +++ b/features/src/git/install.sh @@ -0,0 +1,318 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# 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/git-from-src.md +# Maintainer: The VS Code and Codespaces Teams + +# Ensure we're in this feature's directory during build +cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"; + +# install global/common scripts +. ./common/find-version-from-git-tags.sh; + +GIT_VERSION=${VERSION} # 'system' checks the base image first, else installs 'latest' +USE_PPA_IF_AVAILABLE=${PPA} + +GIT_CORE_PPA_ARCHIVE_GPG_KEY=F911AB184317630C59970973E363C90F8F1B6217 + +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.' + exit 1 +fi + +# Bring in ID, ID_LIKE, VERSION_ID, VERSION_CODENAME +. /etc/os-release +# Get an adjusted ID independent of distro variants +if [ "${ID}" = "debian" ] || [ "${ID_LIKE}" = "debian" ]; then + ADJUSTED_ID="debian" +elif [ "${ID}" = "alpine" ]; then + ADJUSTED_ID="alpine" +elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then + ADJUSTED_ID="rhel" + VERSION_CODENAME="${ID}${VERSION_ID}" +else + echo "Linux distro ${ID} not supported." + exit 1 +fi + +if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then + # As of 1 July 2024, mirrorlist.centos.org no longer exists. + # Update the repo files to reference vault.centos.org. + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo +fi + +if type apt-get > /dev/null 2>&1; then + INSTALL_CMD=apt-get +elif type apk > /dev/null 2>&1; then + INSTALL_CMD=apk +elif type microdnf > /dev/null 2>&1; then + INSTALL_CMD=microdnf +elif type dnf > /dev/null 2>&1; then + INSTALL_CMD=dnf +elif type yum > /dev/null 2>&1; then + INSTALL_CMD=yum +else + echo "(Error) Unable to find a supported package manager." + exit 1 +fi + +# Clean up +clean_up() { + case $ADJUSTED_ID in + debian) + rm -rf /var/lib/apt/lists/* + ;; + alpine) + rm -rf /var/cache/apk/* + ;; + rhel) + rm -rf /var/cache/dnf/* + rm -rf /var/cache/yum/* + ;; + esac +} +clean_up + +# Get the list of GPG key servers that are reachable +get_gpg_key_servers() { + local curl_args="" + local keyserver_reachable=false # Flag to indicate if any keyserver is reachable + + if [ ! -z "${KEYSERVER_PROXY}" ]; then + curl_args="--proxy ${KEYSERVER_PROXY}" + fi + + test_keyserver() { + local keyserver="$1" + local keyserver_curl_url="$2" + if curl -s ${curl_args} --max-time 5 "${keyserver_curl_url}" > /dev/null; then + echo "keyserver ${keyserver}" + keyserver_reachable=true + else + echo "(*) Keyserver ${keyserver} is not reachable." >&2 + fi + } + + # Explicitly test these in order because Bash v4.4.20 (Ubuntu Bionic) + # enumerates associative array keys in a different order than Bash v5 + test_keyserver "hkp://keyserver.ubuntu.com" "http://keyserver.ubuntu.com:11371" + test_keyserver "hkp://keyserver.ubuntu.com:80" "http://keyserver.ubuntu.com" + test_keyserver "hkp://keyserver.pgp.com" "http://keyserver.pgp.com:11371" + # Test this server last because keys.openpgp.org strips user IDs from keys unless + # the owner gives permission, which causes gpg in Ubuntu Bionic to reject the key + # (https://github.com/devcontainers/features/issues/1055) + test_keyserver "hkps://keys.openpgp.org" "https://keys.openpgp.org" + + if ! $keyserver_reachable; then + echo "(!) No keyserver is reachable." >&2 + exit 1 + fi +} + +# Import the specified key in a variable name passed in as +receive_gpg_keys() { + local -a keys="(${!1})" + mkdir -p "$(dirname "$2")" + + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + + # Use a temporary location for gpg keys to avoid polluting image + export GNUPGHOME="/tmp/tmp-gnupg" + mkdir -p ${GNUPGHOME} + chmod 700 ${GNUPGHOME} + echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf + # GPG key download sometimes fails for some reason and retrying fixes it. + local retry_count=0 + local gpg_ok="false" + set +e + until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; + do + for key in "${keys[@]}"; do + echo "(*) Downloading GPG key '${key}'..." + gpg --recv-keys "${key}" \ + && gpg --export "${key}" | gpg --dearmor --yes -o "$2" \ + && gpg_ok="true" + if [ "${gpg_ok}" != "true" ]; then + echo "(*) Failed getting key, retrying in 10s..." + (( retry_count++ )) + sleep 10s + fi + done + done + set -e + if [ "${gpg_ok}" = "false" ]; then + echo "(!) Failed to get gpg key." + exit 1 + fi +} + +pkg_mgr_update() { + if [ ${INSTALL_CMD} = "apt-get" ]; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + ${INSTALL_CMD} update -y + fi + elif [ ${INSTALL_CMD} = "apk" ]; then + if [ "$(find /var/cache/apk/* | wc -l)" = "0" ]; then + echo "Running apk update..." + ${INSTALL_CMD} update + fi + elif [ ${INSTALL_CMD} = "dnf" ] || [ ${INSTALL_CMD} = "yum" ]; then + if [ "$(find /var/cache/${INSTALL_CMD}/* | wc -l)" = "0" ]; then + echo "Running ${INSTALL_CMD} check-update ..." + ${INSTALL_CMD} check-update + fi + fi +} + + +# Checks if packages are installed and installs them if not +check_packages() { + if [ ${INSTALL_CMD} = "apt-get" ]; then + if ! dpkg -s "$@" > /dev/null 2>&1; then + pkg_mgr_update + ${INSTALL_CMD} -y install --no-install-recommends "$@" + fi + elif [ ${INSTALL_CMD} = "apk" ]; then + ${INSTALL_CMD} add \ + --no-cache \ + "$@" + elif [ ${INSTALL_CMD} = "dnf" ] || [ ${INSTALL_CMD} = "yum" ]; then + _num_pkgs=$(echo "$@" | tr ' ' \\012 | wc -l) + _num_installed=$(${INSTALL_CMD} -C list installed "$@" | sed '1,/^Installed/d' | wc -l) + if [ ${_num_pkgs} != ${_num_installed} ]; then + pkg_mgr_update + ${INSTALL_CMD} -y install "$@" + fi + elif [ ${INSTALL_CMD} = "microdnf" ]; then + ${INSTALL_CMD} -y install \ + --refresh \ + --best \ + --nodocs \ + --noplugins \ + --setopt=install_weak_deps=0 \ + "$@" + else + echo "Linux distro ${ID} not supported." + exit 1 + fi +} + +export DEBIAN_FRONTEND=noninteractive + +# Debian / Ubuntu packages + +# If the os provided version is "good enough", just install that. +if [ ${GIT_VERSION} = "os-provided" ] || [ ${GIT_VERSION} = "system" ]; then + if type git > /dev/null 2>&1; then + echo "Detected existing system install: $(git version)" + # Clean up + clean_up + exit 0 + fi + + if [ "$INSTALL_CMD" = "apt-get" ]; then + echo "Installing git from OS apt repository" + elif [ "$INSTALL_CMD" = "apk" ]; then + echo "Installing git from OS apk repository" + else + echo "Installing git from OS yum/dnf repository" + fi + if [ $ID = "mariner" ]; then + check_packages ca-certificates + fi + check_packages git + # Clean up + clean_up + exit 0 +fi + +# If ubuntu, PPAs allowed, and latest - install from there +if ([ "${GIT_VERSION}" = "latest" ] || [ "${GIT_VERSION}" = "lts" ] || [ "${GIT_VERSION}" = "current" ]) && [ "${ID}" = "ubuntu" ] && [ "${USE_PPA_IF_AVAILABLE}" = "true" ]; then + echo "Using PPA to install latest git..." + check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr + receive_gpg_keys GIT_CORE_PPA_ARCHIVE_GPG_KEY /usr/share/keyrings/gitcoreppa-archive-keyring.gpg + cat < /etc/apt/sources.list.d/git-core-ppa.list +deb [arch=$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/') signed-by=/usr/share/keyrings/gitcoreppa-archive-keyring.gpg] http://ppa.launchpad.net/git-core/ppa/ubuntu ${VERSION_CODENAME} main +deb-src [arch=$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/') signed-by=/usr/share/keyrings/gitcoreppa-archive-keyring.gpg] http://ppa.launchpad.net/git-core/ppa/ubuntu ${VERSION_CODENAME} main +EOF + ${INSTALL_CMD} update + ${INSTALL_CMD} -y install --no-install-recommends git + rm -rf "/tmp/tmp-gnupg" + rm -rf /var/lib/apt/lists/* + exit 0 +fi + +# Install required packages to build if missing +if [ "${ADJUSTED_ID}" = "debian" ]; then + + check_packages build-essential curl ca-certificates tar gettext libssl-dev zlib1g-dev libcurl?-openssl-dev libexpat1-dev + + check_packages libpcre2-dev + + if [ "${VERSION_CODENAME}" = "focal" ] || [ "${VERSION_CODENAME}" = "bullseye" ]; then + check_packages libpcre2-posix2 + elif [ "${VERSION_CODENAME}" = "bionic" ] || [ "${VERSION_CODENAME}" = "buster" ]; then + check_packages libpcre2-posix0 + else + check_packages libpcre2-posix3 + fi + +elif [ "${ADJUSTED_ID}" = "alpine" ]; then + + # update build dependencies + ${INSTALL_CMD} add --no-cache --update curl grep make zlib-dev + + # ref. + check_packages asciidoc curl-dev expat-dev g++ gcc openssl-dev pcre2-dev perl-dev perl-error python3-dev tcl tk xmlto + +elif [ "${ADJUSTED_ID}" = "rhel" ]; then + check_packages gcc libcurl-devel expat-devel gettext-devel openssl-devel perl-devel zlib-devel cmake pcre2-devel tar gzip ca-certificates + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + if ! type cmp > /dev/null 2>&1; then + check_packages diffutils + fi + if ! type awk > /dev/null 2>&1; then + check_packages gawk + fi + if [ $ID = "mariner" ]; then + check_packages glibc-devel kernel-headers binutils + fi + +else + echo "Linux distro ${ID} not supported." + exit 1 +fi + +# Partial version matching +if [ "$(echo "${GIT_VERSION}" | grep -o '\.' | wc -l)" != "2" ]; then + check_packages git + _find_version_from_git_tags GIT_VERSION https://github.com/git/git; +fi + +echo "Downloading source for ${GIT_VERSION}..." +curl -sL https://github.com/git/git/archive/v${GIT_VERSION}.tar.gz | tar -xzC /tmp 2>&1 +echo "Building..." +cd /tmp/git-${GIT_VERSION} +git_options=("prefix=/usr/local") +git_options+=("sysconfdir=/etc") +git_options+=("USE_LIBPCRE=YesPlease") +if [ "${ADJUSTED_ID}" = "alpine" ]; then + # ref. + git_options+=("NO_REGEX=YesPlease") + git_options+=("NO_GETTEXT=YesPlease") +fi +make -s "${git_options[@]}" all && make -s "${git_options[@]}" install 2>&1 +rm -rf /tmp/git-${GIT_VERSION} +clean_up +echo "Done!" diff --git a/features/src/gitlab-cli/devcontainer-feature.json b/features/src/gitlab-cli/devcontainer-feature.json index dd50345cd..2bc1765a6 100644 --- a/features/src/gitlab-cli/devcontainer-feature.json +++ b/features/src/gitlab-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "gitlab-cli", - "version": "26.8.0", + "version": "26.8.1", "name": "GitLab CLI", "documentationURL": "https://github.com/rapidsai/devcontainers/features/tree/main/src/gitlab-cli", "description": "Installs the GitLab CLI. Auto-detects latest version and installs needed dependencies.", diff --git a/features/src/gitlab-cli/install.sh b/features/src/gitlab-cli/install.sh index eeec4101e..88ec61ba8 100755 --- a/features/src/gitlab-cli/install.sh +++ b/features/src/gitlab-cli/install.sh @@ -23,7 +23,7 @@ gitlab_cli_file_name() { if [[ "${CLI_VERSION}" < "1.47.0" ]]; then arch="${arch:-$(uname -m)}"; else - arch="${arch:-$(dpkg --print-architecture | awk -F'-' '{print $NF}')}"; + arch="${arch:-$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/')}"; os="${os,,}"; fi diff --git a/features/src/mambaforge/devcontainer-feature.json b/features/src/mambaforge/devcontainer-feature.json index db7e1e0e9..fbfeebf5c 100644 --- a/features/src/mambaforge/devcontainer-feature.json +++ b/features/src/mambaforge/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Mambaforge", "id": "mambaforge", - "version": "26.8.1", + "version": "26.8.2", "description": "A feature to install mambaforge", "options": { "version": { diff --git a/features/src/mambaforge/install.sh b/features/src/mambaforge/install.sh index 3089c40b1..0ac1f4550 100644 --- a/features/src/mambaforge/install.sh +++ b/features/src/mambaforge/install.sh @@ -19,7 +19,7 @@ if [[ "$MINIFORGE_VERSION" == latest ]]; then fi wget --no-hsts -q -O /tmp/miniforge.sh \ - "https://github.com/conda-forge/miniforge/releases/download/${MINIFORGE_VERSION}/Miniforge3-${MINIFORGE_VERSION}-Linux-$(uname -p).sh"; + "https://github.com/conda-forge/miniforge/releases/download/${MINIFORGE_VERSION}/Miniforge3-${MINIFORGE_VERSION}-Linux-$(uname -m).sh"; echo "Installing Miniforge..."; # Install Miniforge diff --git a/features/src/ninja/devcontainer-feature.json b/features/src/ninja/devcontainer-feature.json index c0f94f410..cc7902371 100644 --- a/features/src/ninja/devcontainer-feature.json +++ b/features/src/ninja/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Ninja build", "id": "ninja", - "version": "26.8.0", + "version": "26.8.1", "description": "A feature to install ninja-build", "options": { "version": { diff --git a/features/src/ninja/install.sh b/features/src/ninja/install.sh index 04f23c269..9f82f1f2b 100644 --- a/features/src/ninja/install.sh +++ b/features/src/ninja/install.sh @@ -19,7 +19,7 @@ fi _name="ninja-linux"; -if test "$(uname -p)" = "aarch64"; then +if test "$(uname -m)" = "aarch64"; then _name+="-aarch64"; fi diff --git a/features/src/nvhpc/devcontainer-feature.json b/features/src/nvhpc/devcontainer-feature.json index 54b593e56..fc2acae1b 100644 --- a/features/src/nvhpc/devcontainer-feature.json +++ b/features/src/nvhpc/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "NVHPC SDK", "id": "nvhpc", - "version": "26.8.1", + "version": "26.8.2", "description": "A feature to install the NVHPC SDK", "options": { "version": { diff --git a/features/src/nvhpc/install.sh b/features/src/nvhpc/install.sh index c24662182..e48cd9f53 100644 --- a/features/src/nvhpc/install.sh +++ b/features/src/nvhpc/install.sh @@ -36,7 +36,7 @@ chmod 0644 /etc/apt/trusted.gpg.d/*.gpg || true; echo "Adding NVHPC SDK apt repository..."; # Install NVHPC-SDK apt repository -apt-add-repository -y "deb https://developer.download.nvidia.com/hpc-sdk/ubuntu/$(dpkg-architecture -q DEB_BUILD_ARCH) /"; +apt-add-repository -y "deb https://developer.download.nvidia.com/hpc-sdk/ubuntu/$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/') /"; echo "Installing NVHPC SDK..."; @@ -59,7 +59,7 @@ export NVHPC="/opt/nvidia/hpc_sdk"; export NVHPC_VERSION="${NVHPC_VERSION}"; export NVHPC_VERSION_MAJOR="${NVHPC_VERSION_MAJOR}"; export NVHPC_VERSION_MINOR="${NVHPC_VERSION_MINOR}"; -export NVHPC_ROOT="${NVHPC}/Linux_$(uname -p)/${NVHPC_VERSION}"; +export NVHPC_ROOT="${NVHPC}/Linux_$(uname -m)/${NVHPC_VERSION}"; export NVHPC_CUDA_HOME="$(dirname "$(find "$NVHPC_ROOT/cuda" -type f -name 'version.json' | head -n1)")"; export NVHPC_MODULEFILE_DIRS="($(find "${NVHPC}/" -type d -name modulefiles -exec echo -n \"{}\"\ \;))"; diff --git a/features/src/oneapi/devcontainer-feature.json b/features/src/oneapi/devcontainer-feature.json index ad631d206..0db6d35ca 100644 --- a/features/src/oneapi/devcontainer-feature.json +++ b/features/src/oneapi/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Intel oneapi toolchain", "id": "oneapi", - "version": "26.8.0", + "version": "26.8.1", "description": "A feature to install the Intel oneapi toolchain", "options": { "version": { diff --git a/features/src/oneapi/install.sh b/features/src/oneapi/install.sh index 5a6921358..65e9153b8 100644 --- a/features/src/oneapi/install.sh +++ b/features/src/oneapi/install.sh @@ -2,7 +2,7 @@ set -e # Intel only publishes its compilers for x86 -if [[ "$(uname -p)" != "x86_64" ]]; then +if [[ "$(uname -m)" != "x86_64" ]]; then exit 0; fi diff --git a/features/src/rapids-build-utils/devcontainer-feature.json b/features/src/rapids-build-utils/devcontainer-feature.json index 03b34f994..aed128d8b 100644 --- a/features/src/rapids-build-utils/devcontainer-feature.json +++ b/features/src/rapids-build-utils/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "NVIDIA RAPIDS devcontainer build utilities", "id": "rapids-build-utils", - "version": "26.8.6", + "version": "26.8.7", "description": "A feature to install the RAPIDS devcontainer build utilities", "containerEnv": { "BASH_ENV": "/etc/bash.bash_env" diff --git a/features/src/rapids-build-utils/install.sh b/features/src/rapids-build-utils/install.sh index 78f34900a..d03610719 100644 --- a/features/src/rapids-build-utils/install.sh +++ b/features/src/rapids-build-utils/install.sh @@ -21,7 +21,7 @@ check_packages "${PKGS[@]}"; if ! command -V yq >/dev/null 2>&1; then YQ_BINARY="yq"; YQ_BINARY+="_$(uname -s | tr '[:upper:]' '[:lower:]')"; - YQ_BINARY+="_${TARGETARCH:-$(dpkg --print-architecture | awk -F'-' '{print $NF}')}"; + YQ_BINARY+="_${TARGETARCH:-$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/')}"; YQ_VERSION=4.46.1; find_version_from_git_tags YQ_VERSION https://github.com/mikefarah/yq; diff --git a/features/src/rust/devcontainer-feature.json b/features/src/rust/devcontainer-feature.json index 17c97aeac..40ce5f766 100644 --- a/features/src/rust/devcontainer-feature.json +++ b/features/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "26.8.0", + "version": "26.8.1", "name": "Rust", "documentationURL": "https://github.com/rapidsai/devcontainers/features/tree/main/src/rust", "description": "Installs Rust, common Rust utilities, and their required dependencies", diff --git a/features/src/rust/install.sh b/features/src/rust/install.sh index 1e0b08f22..b18a497e0 100644 --- a/features/src/rust/install.sh +++ b/features/src/rust/install.sh @@ -61,7 +61,7 @@ if ! dpkg -s gnupg2 ${lldb_pkg} python3-minimal pkg-config > /dev/null 2>&1; the apt-get install -y --no-install-recommends ${lldb_pkg} python3-minimal libpython3.? pkg-config; fi -architecture="${TARGETARCH:-$(dpkg --print-architecture | awk -F'-' '{print $NF}')}"; +architecture="${TARGETARCH:-$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/')}"; download_architecture="${architecture}"; case ${download_architecture} in diff --git a/features/src/ucx/devcontainer-feature.json b/features/src/ucx/devcontainer-feature.json index a61d2ff34..7b4f1c367 100644 --- a/features/src/ucx/devcontainer-feature.json +++ b/features/src/ucx/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "UCX", "id": "ucx", - "version": "26.8.0", + "version": "26.8.1", "description": "A feature to install UCX", "options": { "version": { diff --git a/features/src/ucx/install.sh b/features/src/ucx/install.sh index 35c54ce77..0ba4291b1 100755 --- a/features/src/ucx/install.sh +++ b/features/src/ucx/install.sh @@ -36,14 +36,14 @@ download_ucx_release() { slug+="-mofed5-cuda${cuda}"; fi - if [ "$(uname -p)" = "x86_64" ]; then + if [ "$(uname -m)" = "x86_64" ]; then # https://github.com/openucx/ucx/releases/download/v1.15.0-rc3/ucx-1.15.0-rc3-ubuntu22.04-mofed5-cuda12-x86_64.tar.bz2 - if ! wget --no-hsts -q -O /tmp/ucx.tar.bz2 "https://github.com/openucx/ucx/releases/download/v${UCX_VERSION}/${slug}-$(uname -p).tar.bz2"; then + if ! wget --no-hsts -q -O /tmp/ucx.tar.bz2 "https://github.com/openucx/ucx/releases/download/v${UCX_VERSION}/${slug}-$(uname -m).tar.bz2"; then # https://github.com/openucx/ucx/releases/download/v1.14.1/ucx-1.14.1-ubuntu22.04-mofed5-cuda12.tar.bz2 wget --no-hsts -q -O /tmp/ucx.tar.bz2 "https://github.com/openucx/ucx/releases/download/v${UCX_VERSION}/${slug}.tar.bz2"; fi else - wget --no-hsts -q -O /tmp/ucx.tar.bz2 "https://github.com/openucx/ucx/releases/download/v${UCX_VERSION}/${slug}-$(uname -p).tar.bz2"; + wget --no-hsts -q -O /tmp/ucx.tar.bz2 "https://github.com/openucx/ucx/releases/download/v${UCX_VERSION}/${slug}-$(uname -m).tar.bz2"; fi } diff --git a/features/src/utils/devcontainer-feature.json b/features/src/utils/devcontainer-feature.json index 9589dd4d9..59782b2d9 100644 --- a/features/src/utils/devcontainer-feature.json +++ b/features/src/utils/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "devcontainer-utils", "id": "utils", - "version": "26.8.2", + "version": "26.8.3", "description": "A feature to install RAPIDS devcontainer utility scripts", "containerEnv": { "BASH_ENV": "/etc/bash.bash_env" diff --git a/features/src/utils/install.sh b/features/src/utils/install.sh index e8c4b1159..aed260f34 100644 --- a/features/src/utils/install.sh +++ b/features/src/utils/install.sh @@ -49,7 +49,7 @@ python3 -m pip install "${_PIP_INSTALL_ARGS[@]}" "${_PIP_UPGRADE_ARGS[@]}" pip; if ! command -V yq >/dev/null 2>&1; then YQ_BINARY="yq"; YQ_BINARY+="_$(uname -s | tr '[:upper:]' '[:lower:]')"; - YQ_BINARY+="_${TARGETARCH:-$(dpkg --print-architecture | awk -F'-' '{print $NF}')}"; + YQ_BINARY+="_${TARGETARCH:-$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/')}"; YQ_VERSION=4.46.1; find_version_from_git_tags YQ_VERSION https://github.com/mikefarah/yq; @@ -197,27 +197,34 @@ find_non_root_user; if test -n "${USERNAME:+x}"; then USERHOME="$(bash -c "echo ~${USERNAME}")"; + # + # Install gh-nv-gha-aws CLI extension + # Doesn't do `gh extension install nv-gha-runners/gh-nv-gha-aws`, + # because that hits GH API rate limits in CI + # if command -V gh >/dev/null 2>&1; then - mkdir -p -m 0755 \ - "$USERHOME/.local" \ - "$USERHOME/.local/share" \ - "$USERHOME/.local/share/gh" \ - "$USERHOME/.local/share/gh/extensions" \ - "$USERHOME/.local/share/gh/extensions/gh-nv-gha-aws" \ - ; - NV_GHA_AWS_VERSION=latest - find_version_from_git_tags NV_GHA_AWS_VERSION https://github.com/nv-gha-runners/gh-nv-gha-aws; - wget --no-hsts -q -O "$USERHOME/.local/share/gh/extensions/gh-nv-gha-aws/gh-nv-gha-aws" \ - "https://github.com/nv-gha-runners/gh-nv-gha-aws/releases/download/v${NV_GHA_AWS_VERSION}/gh-nv-gha-aws_v${NV_GHA_AWS_VERSION}_linux-$(dpkg --print-architecture | awk -F'-' '{print $NF}')"; - chmod 0755 "$USERHOME/.local/share/gh/extensions/gh-nv-gha-aws/gh-nv-gha-aws"; - cat <"$USERHOME/.local/share/gh/extensions/gh-nv-gha-aws/manifest.yml" + # Install for the container user (i.e. root) and non-root remote user (i.e. coder) + for DIR in "/root" "${USERHOME}"; do + mkdir -p -m 0755 \ + "$DIR/.local" \ + "$DIR/.local/share" \ + "$DIR/.local/share/gh" \ + "$DIR/.local/share/gh/extensions" \ + "$DIR/.local/share/gh/extensions/gh-nv-gha-aws" ; + NV_GHA_AWS_VERSION=latest + find_version_from_git_tags NV_GHA_AWS_VERSION https://github.com/nv-gha-runners/gh-nv-gha-aws; + wget --no-hsts -q -O "$DIR/.local/share/gh/extensions/gh-nv-gha-aws/gh-nv-gha-aws" \ + "https://github.com/nv-gha-runners/gh-nv-gha-aws/releases/download/v${NV_GHA_AWS_VERSION}/gh-nv-gha-aws_v${NV_GHA_AWS_VERSION}_linux-$(uname -m | sed -e 's/x86_/amd/' -e 's/aarch/arm/')"; + chmod 0755 "$DIR/.local/share/gh/extensions/gh-nv-gha-aws/gh-nv-gha-aws"; + cat <"$DIR/.local/share/gh/extensions/gh-nv-gha-aws/manifest.yml" owner: nv-gha-runners name: gh-nv-gha-aws host: github.com tag: v${NV_GHA_AWS_VERSION} ispinned: false -path: $USERHOME/.local/share/gh/extensions/gh-nv-gha-aws/gh-nv-gha-aws +path: $DIR/.local/share/gh/extensions/gh-nv-gha-aws/gh-nv-gha-aws EOF + done fi # Add user to the crontab group diff --git a/features/test/_global/scenarios.json b/features/test/_global/scenarios.json index ac1bce87c..2ba1726bc 100644 --- a/features/test/_global/scenarios.json +++ b/features/test/_global/scenarios.json @@ -22,12 +22,12 @@ "installZsh": "true", "upgradePackages": "true" }, - "ghcr.io/devcontainers/features/git:1.3.2": { + "git": { "ppa": "true", "version": "latest" }, "ghcr.io/devcontainers/features/git-lfs:1.2.1": {}, - "ghcr.io/devcontainers/features/github-cli:1.0.12": {}, + "ghcr.io/devcontainers/features/github-cli:1.1.0": {}, "gitlab-cli": { "version": "latest" }, @@ -53,7 +53,7 @@ }, "overrideFeatureInstallOrder": [ "ghcr.io/devcontainers/features/common-utils", - "ghcr.io/devcontainers/features/git", + "./git", "ghcr.io/devcontainers/features/git-lfs", "ghcr.io/devcontainers/features/github-cli", "./gitlab-cli", diff --git a/features/test/git/install_git_from_ppa_bionic.sh b/features/test/git/install_git_from_ppa_bionic.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_ppa_bionic.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_ppa_jammy.sh b/features/test/git/install_git_from_ppa_jammy.sh new file mode 100644 index 000000000..45e4a20bc --- /dev/null +++ b/features/test/git/install_git_from_ppa_jammy.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults + diff --git a/features/test/git/install_git_from_ppa_noble.sh b/features/test/git/install_git_from_ppa_noble.sh new file mode 100644 index 000000000..45e4a20bc --- /dev/null +++ b/features/test/git/install_git_from_ppa_noble.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults + diff --git a/features/test/git/install_git_from_ppa_resolute.sh b/features/test/git/install_git_from_ppa_resolute.sh new file mode 100644 index 000000000..45e4a20bc --- /dev/null +++ b/features/test/git/install_git_from_ppa_resolute.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults + diff --git a/features/test/git/install_git_from_src.sh b/features/test/git/install_git_from_src.sh new file mode 100644 index 000000000..d0ebaa282 --- /dev/null +++ b/features/test/git/install_git_from_src.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version +check "gettext" dpkg-query -l gettext + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +check "git-location" bash -c "which git | grep /usr/local/bin/git" + +check "set-git-config-user-name" bash -c "git config --system user.name devcontainers" +check "gitconfig-file-location" bash -c "ls /etc/gitconfig" +check "gitconfig-contains-name" bash -c "cat /etc/gitconfig | grep 'name = devcontainers'" + +check "usr-local-etc-config-does-not-exist" test ! -f "/usr/local/etc/gitconfig" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_alma-8.sh b/features/test/git/install_git_from_src_alma-8.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_src_alma-8.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_alma-9.sh b/features/test/git/install_git_from_src_alma-9.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_src_alma-9.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_alpine.sh b/features/test/git/install_git_from_src_alpine.sh new file mode 100644 index 000000000..2a26beec5 --- /dev/null +++ b/features/test/git/install_git_from_src_alpine.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_bionic.sh b/features/test/git/install_git_from_src_bionic.sh new file mode 100644 index 000000000..6a1f639cf --- /dev/null +++ b/features/test/git/install_git_from_src_bionic.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version +check "gettext" dpkg-query -l gettext + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_bullseye.sh b/features/test/git/install_git_from_src_bullseye.sh new file mode 100644 index 000000000..6a1f639cf --- /dev/null +++ b/features/test/git/install_git_from_src_bullseye.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version +check "gettext" dpkg-query -l gettext + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_buster.sh b/features/test/git/install_git_from_src_buster.sh new file mode 100644 index 000000000..6a1f639cf --- /dev/null +++ b/features/test/git/install_git_from_src_buster.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version +check "gettext" dpkg-query -l gettext + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_centos-7.sh b/features/test/git/install_git_from_src_centos-7.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_src_centos-7.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_fedora.sh b/features/test/git/install_git_from_src_fedora.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_src_fedora.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_jammy.sh b/features/test/git/install_git_from_src_jammy.sh new file mode 100644 index 000000000..6a1f639cf --- /dev/null +++ b/features/test/git/install_git_from_src_jammy.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version +check "gettext" dpkg-query -l gettext + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_mariner.sh b/features/test/git/install_git_from_src_mariner.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_src_mariner.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_noble.sh b/features/test/git/install_git_from_src_noble.sh new file mode 100644 index 000000000..337226fdc --- /dev/null +++ b/features/test/git/install_git_from_src_noble.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version +check "gettext" dpkg-query -l gettext + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults + diff --git a/features/test/git/install_git_from_src_resolute.sh b/features/test/git/install_git_from_src_resolute.sh new file mode 100644 index 000000000..6a1f639cf --- /dev/null +++ b/features/test/git/install_git_from_src_resolute.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version +check "gettext" dpkg-query -l gettext + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_rocky-8.sh b/features/test/git/install_git_from_src_rocky-8.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_src_rocky-8.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_src_rocky-9.sh b/features/test/git/install_git_from_src_rocky-9.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_src_rocky-9.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_system_alma-8.sh b/features/test/git/install_git_from_system_alma-8.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_system_alma-8.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_system_alma-9.sh b/features/test/git/install_git_from_system_alma-9.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_system_alma-9.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_system_alpine.sh b/features/test/git/install_git_from_system_alpine.sh new file mode 100644 index 000000000..972976a4c --- /dev/null +++ b/features/test/git/install_git_from_system_alpine.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter + +# Report result +reportResults diff --git a/features/test/git/install_git_from_system_centos-7.sh b/features/test/git/install_git_from_system_centos-7.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_system_centos-7.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_system_fedora.sh b/features/test/git/install_git_from_system_fedora.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_system_fedora.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_system_mariner.sh b/features/test/git/install_git_from_system_mariner.sh new file mode 100644 index 000000000..2114dfdf6 --- /dev/null +++ b/features/test/git/install_git_from_system_mariner.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +# Ensure git clone works, i.e. ca-certificates are installed. +check "git clone" bash -c "cd /tmp && git clone https://github.com/devcontainers/feature-starter.git" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_system_rocky-8.sh b/features/test/git/install_git_from_system_rocky-8.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_system_rocky-8.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/install_git_from_system_rocky-9.sh b/features/test/git/install_git_from_system_rocky-9.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/features/test/git/install_git_from_system_rocky-9.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/features/test/git/scenarios.json b/features/test/git/scenarios.json new file mode 100644 index 000000000..7db7f6878 --- /dev/null +++ b/features/test/git/scenarios.json @@ -0,0 +1,218 @@ +{ + "install_git_from_src": { + "image": "ubuntu:noble", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_alpine": { + "image": "mcr.microsoft.com/devcontainers/base:alpine", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_jammy": { + "image": "ubuntu:jammy", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_ppa_jammy": { + "image": "ubuntu:jammy", + "features": { + "git": { + "version": "latest", + "ppa": "true" + } + } + }, + "install_git_from_src_noble": { + "image": "ubuntu:noble", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_ppa_noble": { + "image": "ubuntu:noble", + "features": { + "git": { + "version": "latest", + "ppa": "true" + } + } + }, + "install_git_from_src_resolute": { + "image": "ubuntu:resolute", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_ppa_resolute": { + "image": "ubuntu:resolute", + "features": { + "git": { + "version": "latest", + "ppa": "true" + } + } + }, + "install_git_from_src_bullseye": { + "image": "debian:bullseye", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_centos-7": { + "image": "centos:centos7", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_alma-8": { + "image": "almalinux:8", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_alma-9": { + "image": "almalinux:9", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_rocky-8": { + "image": "rockylinux:8", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_rocky-9": { + "image": "rockylinux:9", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_fedora": { + "image": "fedora", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_mariner": { + "image": "mcr.microsoft.com/cbl-mariner/base/core:2.0", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_system_alpine": { + "image": "mcr.microsoft.com/devcontainers/base:alpine", + "features": { + "git": { + "version": "system", + "ppa": "false" + } + } + }, + "install_git_from_system_centos-7": { + "image": "centos:centos7", + "features": { + "git": { + "version": "system", + "ppa": "true" + } + } + }, + "install_git_from_system_alma-8": { + "image": "almalinux:8", + "features": { + "git": { + "version": "system", + "ppa": "true" + } + } + }, + "install_git_from_system_alma-9": { + "image": "almalinux:9", + "features": { + "git": { + "version": "system", + "ppa": "true" + } + } + }, + "install_git_from_system_rocky-8": { + "image": "rockylinux:8", + "features": { + "git": { + "version": "system", + "ppa": "true" + } + } + }, + "install_git_from_system_rocky-9": { + "image": "rockylinux:9", + "features": { + "git": { + "version": "system", + "ppa": "true" + } + } + }, + "install_git_from_system_fedora": { + "image": "fedora", + "features": { + "git": { + "version": "system", + "ppa": "true" + } + } + }, + "install_git_from_system_mariner": { + "image": "mcr.microsoft.com/cbl-mariner/base/core:2.0", + "features": { + "git": { + "version": "system", + "ppa": "true" + } + } + } +} diff --git a/features/test/git/test.sh b/features/test/git/test.sh new file mode 100644 index 000000000..ce1552eff --- /dev/null +++ b/features/test/git/test.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +# Report result +reportResults diff --git a/features/test/llvm/scenarios.json b/features/test/llvm/scenarios.json index a849b638e..df84fe4fc 100644 --- a/features/test/llvm/scenarios.json +++ b/features/test/llvm/scenarios.json @@ -39,13 +39,5 @@ "version": "17" } } - // }, - // "llvm_dev": { - // "image": "ubuntu:22.04", - // "features": { - // "llvm": { - // "version": "dev" - // } - // } } } diff --git a/features/test/oneapi/oneapi_2023_2_0.sh b/features/test/oneapi/oneapi_2023_2_0.sh index 6499af643..f7a0853b4 100644 --- a/features/test/oneapi/oneapi_2023_2_0.sh +++ b/features/test/oneapi/oneapi_2023_2_0.sh @@ -12,7 +12,7 @@ set -e # Optional: Import test library bundled with the devcontainer CLI source dev-container-features-test-lib -if [[ "$(uname -p)" == "x86_64" ]]; then +if [[ "$(uname -m)" == "x86_64" ]]; then # Feature-specific tests # The 'check' command comes from the dev-container-features-test-lib. diff --git a/features/test/utils/scenarios.json b/features/test/utils/scenarios.json index 90aa6679c..108688222 100644 --- a/features/test/utils/scenarios.json +++ b/features/test/utils/scenarios.json @@ -20,12 +20,12 @@ "installZsh": "true", "upgradePackages": "true" }, - "ghcr.io/devcontainers/features/git:1.3.2": { + "git": { "ppa": "true", "version": "latest" }, "ghcr.io/devcontainers/features/git-lfs:1.2.1": {}, - "ghcr.io/devcontainers/features/github-cli:1.0.12": {}, + "ghcr.io/devcontainers/features/github-cli:1.1.0": {}, "gitlab-cli": {}, "cmake": {}, "ninja": {}, @@ -36,7 +36,7 @@ }, "overrideFeatureInstallOrder": [ "ghcr.io/devcontainers/features/common-utils", - "ghcr.io/devcontainers/features/git", + "./git", "ghcr.io/devcontainers/features/git-lfs", "ghcr.io/devcontainers/features/github-cli", "./gitlab-cli", @@ -67,12 +67,12 @@ "installZsh": "true", "upgradePackages": "true" }, - "ghcr.io/devcontainers/features/git:1.3.2": { + "git": { "ppa": "true", "version": "latest" }, "ghcr.io/devcontainers/features/git-lfs:1.2.1": {}, - "ghcr.io/devcontainers/features/github-cli:1.0.12": {}, + "ghcr.io/devcontainers/features/github-cli:1.1.0": {}, "gitlab-cli": {}, "cmake": {}, "ninja": {}, @@ -83,7 +83,7 @@ }, "overrideFeatureInstallOrder": [ "ghcr.io/devcontainers/features/common-utils", - "ghcr.io/devcontainers/features/git", + "./git", "ghcr.io/devcontainers/features/git-lfs", "ghcr.io/devcontainers/features/github-cli", "./gitlab-cli", @@ -114,12 +114,12 @@ "installZsh": "true", "upgradePackages": "true" }, - "ghcr.io/devcontainers/features/git:1.3.2": { + "git": { "ppa": "true", "version": "latest" }, "ghcr.io/devcontainers/features/git-lfs:1.2.1": {}, - "ghcr.io/devcontainers/features/github-cli:1.0.12": {}, + "ghcr.io/devcontainers/features/github-cli:1.1.0": {}, "gitlab-cli": {}, "cmake": {}, "ninja": {}, @@ -130,7 +130,7 @@ }, "overrideFeatureInstallOrder": [ "ghcr.io/devcontainers/features/common-utils", - "ghcr.io/devcontainers/features/git", + "./git", "ghcr.io/devcontainers/features/git-lfs", "ghcr.io/devcontainers/features/github-cli", "./gitlab-cli", @@ -161,12 +161,12 @@ "installZsh": "true", "upgradePackages": "true" }, - "ghcr.io/devcontainers/features/git:1.3.2": { + "git": { "ppa": "true", "version": "latest" }, "ghcr.io/devcontainers/features/git-lfs:1.2.1": {}, - "ghcr.io/devcontainers/features/github-cli:1.0.12": {}, + "ghcr.io/devcontainers/features/github-cli:1.1.0": {}, "gitlab-cli": {}, "cmake": {}, "ninja": {}, @@ -177,7 +177,7 @@ }, "overrideFeatureInstallOrder": [ "ghcr.io/devcontainers/features/common-utils", - "ghcr.io/devcontainers/features/git", + "./git", "ghcr.io/devcontainers/features/git-lfs", "ghcr.io/devcontainers/features/github-cli", "./gitlab-cli", diff --git a/image/.devcontainer/devcontainer.json b/image/.devcontainer/devcontainer.json index 00d2a7bd4..c7189630e 100644 --- a/image/.devcontainer/devcontainer.json +++ b/image/.devcontainer/devcontainer.json @@ -22,14 +22,14 @@ "installZsh": "true", "upgradePackages": "true" }, - "ghcr.io/devcontainers/features/git:1.3.2": { + "./features/src/git": { "ppa": "true", "version": "latest" }, "ghcr.io/devcontainers/features/git-lfs:1.2.1": { "autoPull": false }, - "ghcr.io/devcontainers/features/github-cli:1.0.12": {}, + "ghcr.io/devcontainers/features/github-cli:1.1.0": {}, "./features/src/gitlab-cli": {}, "./features/src/cmake": {}, "./features/src/ninja": { @@ -42,7 +42,7 @@ }, "overrideFeatureInstallOrder": [ "ghcr.io/devcontainers/features/common-utils", - "ghcr.io/devcontainers/features/git", + "./features/src/git", "ghcr.io/devcontainers/features/git-lfs", "ghcr.io/devcontainers/features/github-cli", "./features/src/gitlab-cli", diff --git a/matrix.yml b/matrix.yml index 0c7d884af..2929df725 100644 --- a/matrix.yml +++ b/matrix.yml @@ -83,100 +83,105 @@ include: - os: "ubuntu:20.04" images: - - { features: [*python, *dood, *gcc_7, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_bionic, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_7, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_bionic, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_8, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_bionic, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_8, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_bionic, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_9, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_bionic, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_9, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_bionic, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_10, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_bionic, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_10, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_bionic, *cccl_dev], env: *gcc_env } - - - { features: [*python, *dood, *llvm_14, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_bionic, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_14, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_bionic, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *gcc_7, *clang_extra_cccl, *clangd_dev_bionic, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_7, *clang_extra_cccl, *clangd_dev_bionic, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_8, *clang_extra_cccl, *clangd_dev_bionic, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_8, *clang_extra_cccl, *clangd_dev_bionic, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_9, *clang_extra_cccl, *clangd_dev_bionic, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_9, *clang_extra_cccl, *clangd_dev_bionic, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_10, *clang_extra_cccl, *clangd_dev_bionic, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_10, *clang_extra_cccl, *clangd_dev_bionic, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + + - { features: [*python, *dood, *llvm_14, *clang_extra_cccl, *clangd_dev_bionic, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_14, *clang_extra_cccl, *clangd_dev_bionic, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } - os: "ubuntu:22.04" images: - - { features: [*python, *dood, *gcc_11, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_11, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_11, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_11, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_12, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_12, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_12, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_12, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_11, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_11, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_11, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_11, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_12, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_12, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_12, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_12, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } # This is only used for testing python -- CTKk 12.0 + gcc13 don't play nice together, but # that doesn't matter for running python tests, and pinning all python jobs at 13 simplifies # things significantly. - - { features: [*python, *dood, *gcc_13, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *gcc_env } - - - { features: [*python, *dood, *llvm_15, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_15, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_15, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_15, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_16, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_16, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_16, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_16, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_17, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_17, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_17, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_17, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_18, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_18, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_18, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_18, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_19, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_19, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_19, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_19, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_20, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_21, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_22, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev_jammy, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *gcc_13, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + + - { features: [*python, *dood, *llvm_15, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_15, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_15, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_15, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_16, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_16, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_16, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_16, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_17, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_17, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_17, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_17, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_18, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_18, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_18, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_18, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_19, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_19, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_19, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_19, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_20, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_21, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_22, *clang_extra_cccl, *clangd_dev_jammy, { <<: *cuda_prev_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } - os: "ubuntu:24.04" images: - { features: [*python, *dood, *nvhpc_prev, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *nvhpc_env } - { features: [*python, *dood, *nvhpc_curr, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *nvhpc_env } - - { features: [*python, *dood, *gcc_13, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_13, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_13, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_13, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_13, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_13, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_14, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_14, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_14, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_14, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_14, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_14, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_15, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_15, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_15, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_15, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_15, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *llvm_20, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_20, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_20, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_21, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_21, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_21, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_22, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_22, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_20, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_20, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_20, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_21, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_21, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_min, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_21, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_22, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_22, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *llvm_env } # cuda-ext images: - - { features: [*python, *dood, *gcc_14, { <<: *cuda_prev_max, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_14, { <<: *cuda_curr_min, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_14, { <<: *cuda_curr_max, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_15, { <<: *cuda_prev_max, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_15, { <<: *cuda_curr_min, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *gcc_15, { <<: *cuda_curr_max, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *gcc_env } - - { features: [*python, *dood, *llvm_20, { <<: *cuda_prev_max, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_20, { <<: *cuda_curr_min, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_20, { <<: *cuda_curr_max, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_21, { <<: *cuda_prev_max, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_21, { <<: *cuda_curr_min, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_21, { <<: *cuda_curr_max, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_22, { <<: *cuda_prev_max, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_22, { <<: *cuda_curr_min, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } - - { features: [*python, *dood, *llvm_22, { <<: *cuda_curr_max, <<: *cccl_cuda_ext_opts }, *clang_extra_cccl, *clangd_dev, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *gcc_14, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_14, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_min, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_14, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_15, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *gcc_15, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_min, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *gcc_env } + - { features: [*python, *dood, *llvm_20, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_20, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_min, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_20, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_21, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_21, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_min, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_21, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_22, *clang_extra_cccl, *clangd_dev, { <<: *cuda_prev_max, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_22, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_min, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *llvm_env } + - { features: [*python, *dood, *llvm_22, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *llvm_env } + +- os: "ubuntu:26.04" + images: + - { features: [*python, *dood, *gcc_15, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_opts }, *cccl_dev], env: *gcc_env } + + # cuda-ext images: + - { features: [*python, *dood, *gcc_15, *clang_extra_cccl, *clangd_dev, { <<: *cuda_curr_max, <<: *cccl_cuda_ext_opts }, *cccl_dev], env: *gcc_env } - os: "windows" images: @@ -206,13 +211,13 @@ include: - os: "ubuntu:24.04" images: # cuda - - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_prev_max_rapids], env: *gcc_env_rapids } - - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_min], env: *gcc_env_rapids } - - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_max], env: *gcc_env_rapids } - - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_max_rapids], env: *gcc_env_rapids } + - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_prev_max_rapids ], env: *gcc_env_rapids } + - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_min ], env: *gcc_env_rapids } + - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_max ], env: *gcc_env_rapids } + - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_max_rapids ], env: *gcc_env_rapids } - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_prev_max_rapids, *ucx_rapids, *openmpi], env: *gcc_env_rapids } - - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_min, *ucx_rapids, *openmpi], env: *gcc_env_rapids } - - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_max, *ucx_rapids, *openmpi], env: *gcc_env_rapids } + - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_min, *ucx_rapids, *openmpi], env: *gcc_env_rapids } + - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_max, *ucx_rapids, *openmpi], env: *gcc_env_rapids } - { features: [*gcc_rapids, *python_rapids, *clang_extra_rapids, *clangd_dev, *cuda_curr_max_rapids, *ucx_rapids, *openmpi], env: *gcc_env_rapids } # mambaforge diff --git a/scripts/copy-common-scripts.sh b/scripts/copy-common-scripts.sh index 24283e7d3..d9814fc08 100755 --- a/scripts/copy-common-scripts.sh +++ b/scripts/copy-common-scripts.sh @@ -4,5 +4,3 @@ cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/.."; find ./features/src -mindepth 1 -maxdepth 1 -type d -exec \ bash -c 'rm -rf {}/common && cp -ar ./features/common {}/' \; - -cp ./features/common/find-version-from-git-tags.sh ./features/src/utils/opt/devcontainer/bin/sccache/find-version-from-git-tags.sh