Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions .changesets/devcontainer-none.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
release: none
summary: Add devcontainer config and fix some things to hyperloop-firmware-toolchain

Use **Ubuntu 22.04** instead of 24.04 in the package image to eliminate the ubuntu 20.04 Focal hack. Also adds **devcontainer** config and installs **stlink-server**.
3 changes: 3 additions & 0 deletions .devcontainer/Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM ghcr.io/hyperloop-upv/hyperloop-firmware-toolchain:latest
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The devcontainer base image is referenced as :latest, which makes the environment non-reproducible and can break developers unexpectedly when the image is updated. Prefer pinning to a specific version tag and/or digest, and update it intentionally when toolchain changes are needed.

Suggested change
FROM ghcr.io/hyperloop-upv/hyperloop-firmware-toolchain:latest
FROM ghcr.io/hyperloop-upv/hyperloop-firmware-toolchain:1.0.0

Copilot uses AI. Check for mistakes.

WORKDIR /workspaces
22 changes: 22 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "ST-LIB Dev Container",
"build": {
"dockerfile": "Containerfile"
},
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"containerEnv": {
"CONTAINER_NAME": "stm32-project"
},
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools",
"marus25.cortex-debug",
"twxs.cmake",
"ms-vscode.cmake-tools"
]
}
},
"containerUser": "root",
"updateRemoteUserUID": true
}
62 changes: 32 additions & 30 deletions ci/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,45 +1,47 @@
FROM ubuntu:24.04
FROM ubuntu:22.04

ARG DEBIAN_FRONTEND=noninteractive
ARG CUBECLT_VERSION=1.21.0
ARG CUBECLT_INSTALLER=cubeclt_${CUBECLT_VERSION}_installer.sh
ARG UV_INSTALLER_URL=https://astral.sh/uv/install.sh

RUN echo "deb http://security.ubuntu.com/ubuntu focal-security main universe" > /etc/apt/sources.list.d/ubuntu-focal-sources.list && \
apt-get update && \
apt-get install -y --no-install-recommends \
bash ca-certificates curl git git-lfs \
python3 python3-pip python3-venv \
cmake ninja-build \
g++ build-essential \
libncurses5 libusb-1.0-0 \
gdb && \
git lfs install --system && \
rm -rf /var/lib/apt/lists/*
# 1. Install System Dependencies (Revised for Programmer CLI)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential cmake ninja-build git git-lfs \
python3 python3-pip python3-venv curl \
libncurses5 libusb-1.0-0 stlink-tools openocd \
libglib2.0-0 libusb-0.1-4 libsm6 libice6 \
tio cu lsb-release \
&& rm -rf /var/lib/apt/lists/*

RUN curl -LsSf "${UV_INSTALLER_URL}" | sh && \
ln -sf /root/.local/bin/uv /usr/local/bin/uv && \
python3 -m pip install --break-system-packages \
Jinja2==3.1.5 \
GitPython==3.1.43
RUN curl -LsSf https://astral.sh/uv/install.sh | sh && \
ln -sf /root/.local/bin/uv /usr/local/bin/uv

# Install cubeclt (STM32CubeCLT)
WORKDIR /tmp

RUN git clone --depth 1 https://github.com/Hyperloop-UPV/cubeclt.git && \
cd cubeclt && \
git lfs pull --include="${CUBECLT_INSTALLER}" && \
chmod +x ${CUBECLT_INSTALLER} && \
echo | LICENSE_ALREADY_ACCEPTED=1 ./${CUBECLT_INSTALLER} && \
actual_root="$(find /opt/st -maxdepth 1 -type d -name "stm32cubeclt_${CUBECLT_VERSION}*" | head -n1)" && \
test -n "${actual_root}" && \
mkdir -p /opt/ST && \
ln -s "${actual_root}" "/opt/ST/STM32CubeCLT_${CUBECLT_VERSION}" && \
cd / && \
rm -rf /tmp/cubeclt
./${CUBECLT_INSTALLER} --target /tmp/extract --noexec && \
# --- Part A: STM32CubeCLT ---
mkdir -p /opt/st/STM32CubeCLT_${CUBECLT_VERSION} && \
tar -xzf /tmp/extract/st-stm32cubeclt_*.tar.gz -C /opt/st/STM32CubeCLT_${CUBECLT_VERSION} --strip-components=1 && \
cp /tmp/extract/version.txt /opt/st/STM32CubeCLT_${CUBECLT_VERSION}/version.txt && \
# --- Part B: ST-LINK Server ---
export LICENSE_ALREADY_ACCEPTED=1 && \
SERVER_INSTALL=$(ls /tmp/extract/st-stlink-server.*.install.sh) && \
Comment on lines +28 to +32
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CubeCLT/ST-LINK server extraction uses broad globs/ls for selecting installer artifacts (e.g., st-stm32cubeclt_*.tar.gz and st-stlink-server.*.install.sh). If more than one file matches (or none match), the build will either fail or pick an arbitrary result. Consider resolving a single expected file deterministically (e.g., find ... -print -quit plus an explicit check) and failing with a clear error when the artifact isn’t found or multiple candidates exist.

Suggested change
tar -xzf /tmp/extract/st-stm32cubeclt_*.tar.gz -C /opt/st/STM32CubeCLT_${CUBECLT_VERSION} --strip-components=1 && \
cp /tmp/extract/version.txt /opt/st/STM32CubeCLT_${CUBECLT_VERSION}/version.txt && \
# --- Part B: ST-LINK Server ---
export LICENSE_ALREADY_ACCEPTED=1 && \
SERVER_INSTALL=$(ls /tmp/extract/st-stlink-server.*.install.sh) && \
CUBECLT_ARCHIVE_COUNT=$(find /tmp/extract -maxdepth 1 -type f -name 'st-stm32cubeclt_*.tar.gz' | wc -l) && \
[ "$CUBECLT_ARCHIVE_COUNT" -eq 1 ] || { echo "Expected exactly one STM32CubeCLT archive in /tmp/extract, found $CUBECLT_ARCHIVE_COUNT" >&2; find /tmp/extract -maxdepth 1 -type f -name 'st-stm32cubeclt_*.tar.gz' >&2; exit 1; } && \
CUBECLT_ARCHIVE=$(find /tmp/extract -maxdepth 1 -type f -name 'st-stm32cubeclt_*.tar.gz' -print -quit) && \
tar -xzf "$CUBECLT_ARCHIVE" -C /opt/st/STM32CubeCLT_${CUBECLT_VERSION} --strip-components=1 && \
cp /tmp/extract/version.txt /opt/st/STM32CubeCLT_${CUBECLT_VERSION}/version.txt && \
# --- Part B: ST-LINK Server ---
export LICENSE_ALREADY_ACCEPTED=1 && \
SERVER_INSTALL_COUNT=$(find /tmp/extract -maxdepth 1 -type f -name 'st-stlink-server.*.install.sh' | wc -l) && \
[ "$SERVER_INSTALL_COUNT" -eq 1 ] || { echo "Expected exactly one ST-LINK Server installer in /tmp/extract, found $SERVER_INSTALL_COUNT" >&2; find /tmp/extract -maxdepth 1 -type f -name 'st-stlink-server.*.install.sh' >&2; exit 1; } && \
SERVER_INSTALL=$(find /tmp/extract -maxdepth 1 -type f -name 'st-stlink-server.*.install.sh' -print -quit) && \

Copilot uses AI. Check for mistakes.
sh "$SERVER_INSTALL" --target /tmp/server_extract --noexec && \
cp /tmp/server_extract/stlink-server /usr/bin/stlink-server && \
chmod +x /usr/bin/stlink-server && \
# --- Part C: FIX THE PATH MISMATCH ---
# Create the directory structure the VS Code extension expects
mkdir -p /usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer && \
ln -s /opt/st/STM32CubeCLT_${CUBECLT_VERSION}/STM32CubeProgrammer/bin /usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin && \
# Cleanup
cd / && rm -rf /tmp/cubeclt /tmp/extract /tmp/server_extract

ENV STM32_CLT_ROOT=/opt/ST/STM32CubeCLT_${CUBECLT_VERSION}
ENV HYPER_STM32CLT_ROOT=/opt/ST/STM32CubeCLT_${CUBECLT_VERSION}
ENV PATH="/root/.local/bin:${STM32_CLT_ROOT}/GNU-tools-for-STM32/bin:${STM32_CLT_ROOT}/STM32CubeProgrammer/bin:${STM32_CLT_ROOT}/CMake/bin:${STM32_CLT_ROOT}/Ninja/bin:${PATH}"
ENV STM32_CLT_ROOT=/opt/st/STM32CubeCLT_${CUBECLT_VERSION}
ENV HYPER_STM32CLT_ROOT=/opt/st/STM32CubeCLT_${CUBECLT_VERSION}
ENV PATH="/root/.local/bin:${STM32_CLT_ROOT}/GNU-tools-for-STM32/bin:${STM32_CLT_ROOT}/STM32CubeProgrammer/bin:${STM32_CLT_ROOT}/STLink-gdb-server/bin:${STM32_CLT_ROOT}/CMake/bin:${STM32_CLT_ROOT}/Ninja/bin:${PATH}"

WORKDIR /workspace
WORKDIR /workspaces
Loading