Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 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 Noble hack. Also adds **devcontainer** config and installs **stlink-server**.
Comment thread
FoniksFox marked this conversation as resolved.
Outdated
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

Copilot AI Apr 5, 2026

Copy link

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
25 changes: 25 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "ST-LIB Dev Container",
"build": {
"dockerfile": "Containerfile"
},
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"runArgs": [
"--userns=keep-id"
],
Comment thread
FoniksFox marked this conversation as resolved.
Outdated
"containerEnv": {
"CONTAINER_NAME": "stm32-project"
},
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools",
"marus25.cortex-debug",
"twxs.cmake",
"ms-vscode.cmake-tools"
]
}
},
"containerUser": "root",
"updateRemoteUserUID": true
}
64 changes: 33 additions & 31 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
ENV DEBIAN_FRONTEND=noninteractive
Comment thread
FoniksFox marked this conversation as resolved.
Outdated
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

Copilot AI Apr 5, 2026

Copy link

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