Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .github/workflows/test-pr-arm64.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: "PR - Test Updated Features (arm64)"
on:
pull_request:
# NOTE: To extend this workflow to other features, add path entries below
# following the same pattern, e.g.:
# - "src/<feature-name>/**"
# - "test/<feature-name>/**"
paths:
- "src/powershell/**"
- "test/powershell/**"

jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
features: ${{ steps.filter.outputs.changes }}
steps:
- uses: dorny/paths-filter@v3
id: filter
with:
# NOTE: To extend this workflow to other features, add filter entries below
# following the same pattern, e.g.:
# <feature-name>: ./**/<feature-name>/**
filters: |
powershell: ./**/powershell/**

test:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}
needs: [detect-changes]
runs-on: ubuntu-24.04-arm
continue-on-error: true
strategy:
matrix:
features: ${{ fromJSON(needs.detect-changes.outputs.features) }}
baseImage:
[
"ubuntu:focal",
"ubuntu:jammy",
"debian:11",
"debian:12",
"mcr.microsoft.com/devcontainers/base:ubuntu",
"mcr.microsoft.com/devcontainers/base:debian",
"mcr.microsoft.com/devcontainers/base:noble"
]
steps:
- uses: actions/checkout@v4

- name: "Install latest devcontainer CLI"
run: npm install -g @devcontainers/cli

- name: "Generating tests for '${{ matrix.features }}' against '${{ matrix.baseImage }}'"
run: devcontainer features test --skip-scenarios -f ${{ matrix.features }} -i ${{ matrix.baseImage }} .

test-scenarios:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
needs: [detect-changes]
runs-on: ubuntu-24.04-arm
continue-on-error: true
strategy:
matrix:
features: ${{ fromJSON(needs.detect-changes.outputs.features) }}
steps:
- uses: actions/checkout@v4

- name: "Install latest devcontainer CLI"
run: npm install -g @devcontainers/cli

- name: "Testing '${{ matrix.features }}' scenarios"
run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated .

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
80 changes: 40 additions & 40 deletions src/conda/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
{
"id": "conda",
"version": "1.0.10",
"name": "Conda",
"description": "A cross-platform, language-agnostic binary package manager",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/conda",
"options": {
"version": {
"type": "string",
"proposals": [
"latest",
"4.11.0",
"4.12.0"
],
"default": "latest",
"description": "Select or enter a conda version."
},
"addCondaForge": {
"type": "boolean",
"default": false,
"description": "Add conda-forge channel to the config?"
}
"id": "conda",
"version": "1.2.5",
"name": "Conda",
"description": "A cross-platform, language-agnostic binary package manager",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/conda",
"options": {
"version": {
"type": "string",
"proposals": [
"latest",
"4.11.0",
"4.12.0"
],
"default": "latest",
"description": "Select or enter a conda version."
},
"containerEnv": {
"CONDA_DIR": "/opt/conda",
"CONDA_SCRIPT":"/opt/conda/etc/profile.d/conda.sh",
"PATH": "/opt/conda/bin:${PATH}"
},
"customizations": {
"vscode": {
"settings": {
"github.copilot.chat.codeGeneration.instructions": [
{
"text": "This dev container includes the conda package manager pre-installed and available on the `PATH` for data science and Python development. Additional packages installed using Conda will be downloaded from Anaconda or another repository configured by the user. A user can install different versions of Python than the one in this dev container by running a command like: conda install python=3.7"
}
]
}
}
},
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils"
]
"addCondaForge": {
"type": "boolean",
"default": false,
"description": "Add conda-forge channel to the config?"
}
},
"containerEnv": {
"CONDA_DIR": "/opt/conda",
"CONDA_SCRIPT": "/opt/conda/etc/profile.d/conda.sh",
"PATH": "/opt/conda/bin:${PATH}"
},
"customizations": {
"vscode": {
"settings": {
"github.copilot.chat.codeGeneration.instructions": [
{
"text": "This dev container includes the conda package manager pre-installed and available on the `PATH` for data science and Python development. Additional packages installed using Conda will be downloaded from Anaconda or another repository configured by the user. A user can install different versions of Python than the one in this dev container by running a command like: conda install python=3.7"
}
]
}
}
},
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils"
]
}
76 changes: 67 additions & 9 deletions src/conda/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,78 @@ if ! conda --version &> /dev/null ; then
usermod -a -G conda "${USERNAME}"

# Install dependencies
check_packages curl ca-certificates gnupg2
check_packages curl ca-certificates

echo "Installing Conda..."

curl -sS https://repo.anaconda.com/pkgs/misc/gpgkeys/anaconda.asc | gpg --dearmor > /usr/share/keyrings/conda-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/conda-archive-keyring.gpg] https://repo.anaconda.com/pkgs/misc/debrepo/conda stable main" > /etc/apt/sources.list.d/conda.list
apt-get update -y

CONDA_PKG="conda=${VERSION}-0"
# Download .deb package directly from repository (bypassing SHA1 signature issue)
TEMP_DEB="$(mktemp -t conda_XXXXXX.deb)"
CONDA_REPO_BASE="https://repo.anaconda.com/pkgs/misc/debrepo/conda"

# Determine package filename based on requested version
ARCH="$(dpkg --print-architecture 2>/dev/null || echo "amd64")"
PACKAGES_URL="https://repo.anaconda.com/pkgs/misc/debrepo/conda/dists/stable/main/binary-${ARCH}/Packages"

if [ "${VERSION}" = "latest" ]; then
CONDA_PKG="conda"
# For latest, we need to query the repository to find the current version
echo "Fetching package list to determine latest version..."
CONDA_PKG_INFO=$(curl -fsSL "${PACKAGES_URL}" | grep -A 30 "^Package: conda$" | head -n 31)
CONDA_VERSION=$(echo "${CONDA_PKG_INFO}" | grep "^Version:" | head -n 1 | awk '{print $2}')
CONDA_FILENAME=$(echo "${CONDA_PKG_INFO}" | grep "^Filename:" | head -n 1 | awk '{print $2}')

if [ -z "${CONDA_VERSION}" ] || [ -z "${CONDA_FILENAME}" ]; then
echo "ERROR: Could not determine latest conda version or filename from ${PACKAGES_URL}"
echo "This may indicate an unsupported architecture or repository unavailability."
rm -f "${TEMP_DEB}"
exit 1
fi

CONDA_PKG_NAME="${CONDA_FILENAME}"
else
# For specific versions, query the Packages file to find the exact filename
echo "Fetching package list to find version ${VERSION}..."
# Search for version pattern - user may specify 4.12.0 but package has 4.12.0-0
CONDA_PKG_INFO=$(curl -fsSL "${PACKAGES_URL}" | grep -A 30 "^Package: conda$" | grep -B 5 -A 25 "^Version: ${VERSION}")
CONDA_FILENAME=$(echo "${CONDA_PKG_INFO}" | grep "^Filename:" | head -n 1 | awk '{print $2}')

if [ -z "${CONDA_FILENAME}" ]; then
echo "ERROR: Could not find conda version ${VERSION} in ${PACKAGES_URL}"
echo "Please verify the version specified is valid."
rm -f "${TEMP_DEB}"
exit 1
fi

CONDA_PKG_NAME="${CONDA_FILENAME}"
fi

check_packages $CONDA_PKG

# Download the .deb package
CONDA_DEB_URL="${CONDA_REPO_BASE}/${CONDA_PKG_NAME}"
echo "Downloading conda package from ${CONDA_DEB_URL}..."

if ! curl -fsSL "${CONDA_DEB_URL}" -o "${TEMP_DEB}"; then
echo "ERROR: Failed to download conda .deb package from ${CONDA_DEB_URL}"
echo "Please verify the version specified is valid."
rm -f "${TEMP_DEB}"
exit 1
fi

# Verify the package was downloaded successfully
if [ ! -f "${TEMP_DEB}" ] || [ ! -s "${TEMP_DEB}" ]; then
echo "ERROR: Conda .deb package file is missing or empty"
rm -f "${TEMP_DEB}"
exit 1
fi

# Install the package using apt (which handles dependencies automatically)
echo "Installing conda package..."
if ! apt-get install -y "${TEMP_DEB}"; then
echo "ERROR: Failed to install conda package"
rm -f "${TEMP_DEB}"
exit 1
fi

# Clean up downloaded package
rm -f "${TEMP_DEB}"

CONDA_SCRIPT="/opt/conda/etc/profile.d/conda.sh"
. $CONDA_SCRIPT
Expand Down
4 changes: 2 additions & 2 deletions src/node/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "node",
"version": "1.7.0",
"version": "1.7.1",
"name": "Node.js (via nvm), yarn and pnpm.",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/node",
"description": "Installs Node.js, nvm, yarn, pnpm, and needed dependencies.",
Expand Down Expand Up @@ -78,4 +78,4 @@
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils"
]
}
}
12 changes: 3 additions & 9 deletions src/node/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,9 @@ install_yarn() {
# via apt-get on Debian systems
if ! type yarn >/dev/null 2>&1; then
# Import key safely (new method rather than deprecated apt-key approach) and install
if [ "${VERSION_CODENAME}" = "trixie" ]; then
# Trixie requires fetching the key from keys.openpgp.org
mkdir -p /etc/apt/keyrings
curl -fsSL "https://keys.openpgp.org/vks/v1/by-fingerprint/72ECF46A56B4AD39C907BBB71646B01B86E50310" | gpg --dearmor --yes -o /etc/apt/keyrings/yarn-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/yarn-archive-keyring.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
else
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor > /usr/share/keyrings/yarn-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/yarn-archive-keyring.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
fi
mkdir -p /etc/apt/keyrings
curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor --yes -o /etc/apt/keyrings/yarn-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/yarn-archive-keyring.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
apt-get update
apt-get -y install --no-install-recommends yarn
else
Expand Down
2 changes: 1 addition & 1 deletion src/powershell/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Installs PowerShell along with needed dependencies. Useful for base Dockerfiles

```json
"features": {
"ghcr.io/devcontainers/features/powershell:1": {}
"ghcr.io/devcontainers/features/powershell:2": {}
}
```

Expand Down
12 changes: 7 additions & 5 deletions src/powershell/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "powershell",
"version": "1.5.1",
"version": "2.0.1",
"name": "PowerShell",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/powershell",
"description": "Installs PowerShell along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.",
Expand All @@ -9,18 +9,20 @@
"type": "string",
"proposals": [
"latest",
"lts",
"preview",
"stable",
"none",
"7.4",
"7.3",
"7.2"
"7.5",
"7.4"
],
"default": "latest",
"description": "Select or enter a version of PowerShell."
},
"modules": {
"type": "string",
"default": "",
"description": "Optional comma separated list of PowerShell modules to install. If you need to install a specific version of a module, use '==' to specify the version (e.g. 'az.resources==2.5.0')"
"description": "Optional comma separated list of PowerShell modules to install. If you need to install a specific version of a module, use '==' to specify the version (e.g. 'az.resources==2.5.0')."
},
"powershellProfileURL": {
"type": "string",
Expand Down
Loading
Loading