Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
41 changes: 0 additions & 41 deletions .devcontainer.json

This file was deleted.

81 changes: 81 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"name": "Home Assistant Dev",
"context": "..",
"dockerFile": "../Dockerfile.dev",
"postCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder} && scripts/setup",
"postStartCommand": "scripts/bootstrap",
"containerEnv": {
"PYTHONASYNCIODEBUG": "1"
},
"features": {
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {},
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"appPort": [
"9000:9000", // OCPP
"8123:8123", // Home Assistant
"5683:5683/udp" // Shelly integration
],
"runArgs": [
"-e",
"GIT_EDITOR=code --wait",
"--security-opt",
"label=disable"
],
"customizations": {
"vscode": {
"extensions": [
"charliermarsh.ruff",
"ms-python.pylint",
"ms-python.vscode-pylance",
"visualstudioexptteam.vscodeintellicode",
"redhat.vscode-yaml",
"esbenp.prettier-vscode",
"GitHub.vscode-pull-request-github",
"GitHub.copilot"
],
// Please keep this file in sync with settings in home-assistant/.vscode/settings.default.json
"settings": {
"python.experiments.optOutFrom": [
"pythonTestAdapter"
],
"python.defaultInterpreterPath": "/home/vscode/.local/ha-venv/bin/python",
"python.pythonPath": "/home/vscode/.local/ha-venv/bin/python",
"python.terminal.activateEnvInCurrentTerminal": true,
"python.testing.pytestArgs": [
"--no-cov"
],
"pylint.importStrategy": "fromEnvironment",
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"files.trimTrailingWhitespace": true,
"terminal.integrated.profiles.linux": {
"zsh": {
"path": "/usr/bin/zsh"
}
},
"terminal.integrated.defaultProfile.linux": "zsh",
"yaml.customTags": [
"!input scalar",
"!secret scalar",
"!include_dir_named scalar",
"!include_dir_list scalar",
"!include_dir_merge_list scalar",
"!include_dir_merge_named scalar"
],
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
},
"json.schemas": [
{
"fileMatch": [
"homeassistant/components/*/manifest.json"
],
"url": "${containerWorkspaceFolder}/scripts/json_schemas/manifest_schema.json"
}
]
}
}
}
}
63 changes: 63 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Automatically generated by hassfest.
#
# To update, run python3 -m script.hassfest -p docker
ARG BUILD_FROM
FROM ${BUILD_FROM}

# Synchronize with homeassistant/core.py:async_stop
ENV \
S6_SERVICES_GRACETIME=240000 \
UV_SYSTEM_PYTHON=true \
UV_NO_CACHE=true

ARG QEMU_CPU

# Home Assistant S6-Overlay
COPY rootfs /

# Needs to be redefined inside the FROM statement to be set for RUN commands
ARG BUILD_ARCH
# Get go2rtc binary
RUN \
case "${BUILD_ARCH}" in \
"aarch64") go2rtc_suffix='arm64' ;; \
"armhf") go2rtc_suffix='armv6' ;; \
"armv7") go2rtc_suffix='arm' ;; \
*) go2rtc_suffix=${BUILD_ARCH} ;; \
esac \
&& curl -L https://github.com/AlexxIT/go2rtc/releases/download/v1.9.9/go2rtc_linux_${go2rtc_suffix} --output /bin/go2rtc \
&& chmod +x /bin/go2rtc \
# Verify go2rtc can be executed
&& go2rtc --version
Comment on lines +20 to +31
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add checksum / signature verification for downloaded go2rtc binary

The image blindly downloads an executable from GitHub and runs it.
Without verifying a checksum / GPG signature this is a supply-chain risk: the URL can be hijacked or the asset replaced, and the malicious binary would run during build time with root privileges.
At minimum, fetch the release’s SHA-256 from the GitHub API (or bundle a known hash in the repo) and validate it before chmod +x.

-    && curl -L https://github.com/AlexxIT/go2rtc/releases/download/v1.9.9/go2rtc_linux_${go2rtc_suffix} --output /bin/go2rtc \
-    && chmod +x /bin/go2rtc \
+    && curl -L -f https://github.com/AlexxIT/go2rtc/releases/download/v1.9.9/go2rtc_linux_${go2rtc_suffix} -o /tmp/go2rtc \
+    && echo "<expected-sha256>  /tmp/go2rtc" | sha256sum -c - \
+    && install -m 0755 /tmp/go2rtc /bin/go2rtc \
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Get go2rtc binary
RUN \
case "${BUILD_ARCH}" in \
"aarch64") go2rtc_suffix='arm64' ;; \
"armhf") go2rtc_suffix='armv6' ;; \
"armv7") go2rtc_suffix='arm' ;; \
*) go2rtc_suffix=${BUILD_ARCH} ;; \
esac \
&& curl -L https://github.com/AlexxIT/go2rtc/releases/download/v1.9.9/go2rtc_linux_${go2rtc_suffix} --output /bin/go2rtc \
&& chmod +x /bin/go2rtc \
# Verify go2rtc can be executed
&& go2rtc --version
# Get go2rtc binary
RUN \
case "${BUILD_ARCH}" in \
"aarch64") go2rtc_suffix='arm64' ;; \
"armhf") go2rtc_suffix='armv6' ;; \
"armv7") go2rtc_suffix='arm' ;; \
*) go2rtc_suffix=${BUILD_ARCH} ;; \
esac \
&& curl -L -f https://github.com/AlexxIT/go2rtc/releases/download/v1.9.9/go2rtc_linux_${go2rtc_suffix} -o /tmp/go2rtc \
&& echo "<expected-sha256> /tmp/go2rtc" | sha256sum -c - \
&& install -m 0755 /tmp/go2rtc /bin/go2rtc \
# Verify go2rtc can be executed
&& go2rtc --version
🤖 Prompt for AI Agents
In Dockerfile lines 20 to 31, the downloaded go2rtc binary is not verified for
integrity, posing a supply-chain risk. To fix this, add a step to fetch the
SHA-256 checksum for the specific go2rtc release from the GitHub API or use a
pre-stored known hash, then verify the downloaded binary's checksum matches
before running chmod +x. If the checksum does not match, the build should fail
to prevent using a potentially tampered binary.


# Install uv
RUN pip3 install uv==0.7.1

WORKDIR /usr/src

## Setup Home Assistant Core dependencies
COPY requirements.txt homeassistant/
COPY homeassistant/package_constraints.txt homeassistant/homeassistant/
RUN \
uv pip install \
--no-build \
-r homeassistant/requirements.txt

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Package constraints file copied but not applied

homeassistant/package_constraints.txt is present yet the install line omits --constraint. Skipping it can pull in versions that violate HA’s tested matrix and break runtime.

-    uv pip install \
-        --no-build \
-        -r homeassistant/requirements.txt
+    uv pip install \
+        --no-build \
+        -r homeassistant/requirements.txt \
+        --constraint homeassistant/homeassistant/package_constraints.txt
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uv pip install \
--no-build \
-r homeassistant/requirements.txt
uv pip install \
--no-build \
-r homeassistant/requirements.txt \
--constraint homeassistant/homeassistant/package_constraints.txt
🤖 Prompt for AI Agents
In Dockerfile lines 42 to 45, the pip install command is missing the
--constraint option to apply the package constraints from
homeassistant/package_constraints.txt. Modify the pip install command to include
--constraint homeassistant/package_constraints.txt before the -r option to
ensure package versions adhere to Home Assistant's tested matrix and prevent
runtime issues.

COPY requirements_all.txt home_assistant_frontend-* home_assistant_intents-* homeassistant/
RUN \
if ls homeassistant/home_assistant_*.whl 1> /dev/null 2>&1; then \
uv pip install homeassistant/home_assistant_*.whl; \
fi \
&& uv pip install \
--no-build \
-r homeassistant/requirements_all.txt

## Setup Home Assistant Core
COPY . homeassistant/
RUN \
uv pip install \
-e ./homeassistant \
&& python3 -m compileall \
homeassistant/homeassistant

WORKDIR /config
61 changes: 61 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
FROM mcr.microsoft.com/vscode/devcontainers/base:debian

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

RUN \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
Comment on lines +5 to +8
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

apt-key is deprecated; migrate to keyring file

apt-key add - will be removed in Debian 13. Use the recommended keyring approach to avoid future build failures.

-curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
+curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg | \
+  gpg --dearmor -o /etc/apt/keyrings/yarn.gpg && \
+echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/yarn.gpg] \
+  https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RUN \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
RUN \
curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg | \
gpg --dearmor -o /etc/apt/keyrings/yarn.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/yarn.gpg] \
https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
🤖 Prompt for AI Agents
In Dockerfile.dev around lines 5 to 8, the use of `apt-key add -` is deprecated
and will be removed in Debian 13. Replace this with the recommended approach by
downloading the GPG key and saving it to a keyring file under
/usr/share/keyrings/, then reference this keyring in the apt sources list entry.
This avoids using `apt-key` and ensures compatibility with future Debian
releases.

# Additional library needed by some tests and accordingly by VScode Tests Discovery
bluez \
ffmpeg \
libudev-dev \
libavformat-dev \
libavcodec-dev \
libavdevice-dev \
libavutil-dev \
libgammu-dev \
libswscale-dev \
libswresample-dev \
libavfilter-dev \
libpcap-dev \
libturbojpeg0 \
libyaml-dev \
libxml2 \
git \
cmake \
autoconf \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Add go2rtc binary
COPY --from=ghcr.io/alexxit/go2rtc:latest /usr/local/bin/go2rtc /bin/go2rtc

WORKDIR /usr/src

COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

Comment on lines +31 to +37
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Images pulled with latest tag make the build non-reproducible

Both go2rtc and uv are copied from :latest images, which drift over time. Pin to a digest or exact version tag to guarantee deterministic builds and simplify SBOM / provenance audits.

-COPY --from=ghcr.io/alexxit/go2rtc:latest /usr/local/bin/go2rtc /bin/go2rtc
+COPY --from=ghcr.io/alexxit/go2rtc:v1.9.9@sha256:<digest> /usr/local/bin/go2rtc /bin/go2rtc

Do the same for the uv stage.

🤖 Prompt for AI Agents
In Dockerfile.dev around lines 31 to 37, the COPY commands pull images with the
:latest tag for go2rtc and uv, causing non-reproducible builds. Replace the
:latest tags with specific version tags or image digests for both go2rtc and uv
to ensure deterministic builds and improve SBOM and provenance tracking.

RUN uv python install 3.13.2

USER vscode
ENV VIRTUAL_ENV="/home/vscode/.local/ha-venv"
RUN uv venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

WORKDIR /tmp

# Setup hass-release
RUN git clone --depth 1 https://github.com/home-assistant/hass-release ~/hass-release \
&& uv pip install -e ~/hass-release/

# Install Python dependencies from requirements
COPY requirements.txt ./
COPY homeassistant/package_constraints.txt homeassistant/package_constraints.txt
RUN uv pip install -r requirements.txt
COPY requirements_test.txt requirements_test_pre_commit.txt ./
RUN uv pip install -r requirements_test.txt
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Constraints not respected during dev dependency install

As in the production Dockerfile, the install lines omit --constraint for package_constraints.txt, so local dev containers may end up with different dependency versions than CI.

-uv pip install -r requirements.txt
+uv pip install -r requirements.txt --constraint homeassistant/package_constraints.txt

Apply the same for requirements_test*.txt.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In Dockerfile.dev around lines 52 to 56, the pip install commands for both
requirements.txt and requirements_test.txt do not use the --constraint option
with package_constraints.txt, which can cause inconsistent dependency versions
between local dev and CI environments. Update the RUN commands to include
--constraint=homeassistant/package_constraints.txt when installing both
requirements.txt and requirements_test.txt to ensure consistent dependency
resolution.


WORKDIR /workspaces

# Set the default shell to bash instead of sh
ENV SHELL=/bin/bash
9 changes: 9 additions & 0 deletions scripts/bootstrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh
# Resolve all dependencies that the application requires to run.

# Stop on errors
set -e

cd "$(dirname "$0")/.."

python3 -m pip install -r requirements.txt
Loading
Loading