* fix: dynamic version badge — read from git tag, never hardcoded
The settings panel showed v0.50.87 and the HTTP Server: header said
HermesWebUI/0.50.38 — both hardcoded strings that drift further behind
with every release because there was no mechanism to keep them in sync.
Changes:
- api/updates.py: add _run_git() (moved before _detect_webui_version),
_detect_webui_version(), and WEBUI_VERSION module constant resolved
once at import time via 'git describe --tags --always --dirty'.
Fallback chain: git → api/_version.py → 'unknown'.
- api/routes.py: inject webui_version into GET /api/settings response
so the frontend can read it without a separate API call.
- static/panels.js: loadSettingsPanel() populates .settings-version-badge
from settings.webui_version — one line after the existing api() call.
- static/index.html: replace stale hardcoded 'v0.50.87' with '—'
placeholder; JS overwrites it as soon as the settings panel opens.
- server.py: replace hardcoded 'HermesWebUI/0.50.38' server_version with
'HermesWebUI/' + WEBUI_VERSION.lstrip('v') — stays in sync automatically.
- Dockerfile: add ARG HERMES_VERSION=unknown and write api/_version.py
so Docker images (where .git is excluded) still show the correct tag.
- .github/workflows/release.yml: pass build-args: HERMES_VERSION=${{ github.ref_name }}
to the Docker build step on tag pushes.
- .gitignore: exclude api/_version.py (generated by Docker/CI, never committed).
No manual 'update the version badge' step is required going forward.
Tagging is sufficient — the badge and HTTP header update automatically.
Tests: 18 new tests in tests/test_version_badge.py covering the full
resolution chain, /api/settings injection, HTML placeholder, JS wiring,
and server.py import. 1596 tests pass total.
* fix: address review feedback on PR #790
- api/updates.py: replace exec() with regex parse for api/_version.py
(no supply-chain risk from build artifact; exec unnecessary for one assignment)
- api/updates.py: cap git describe timeout at 3s (was 10s — import-time
stall on NFS/.git would block server startup unnecessarily)
- server.py: lstrip('v') → removeprefix('v') (lstrip strips chars not prefix)
- server.py: emit bare 'HermesWebUI' when version is 'unknown' rather than
'HermesWebUI/unknown' (log aggregators expect semver-ish suffix or none)
- CHANGELOG.md: add v0.50.124 entry for this user-visible change
- tests: rename exec-error test to reflect regex behaviour; add tests for
removeprefix usage and unknown-version header guard (1598 tests total)
---------
Co-authored-by: nesquena-hermes <hermes@nesquena.com>
96 lines
3.0 KiB
Docker
96 lines
3.0 KiB
Docker
FROM python:3.12-slim
|
|
|
|
LABEL maintainer="nesquena"
|
|
LABEL description="Hermes Web UI — browser interface for Hermes Agent"
|
|
|
|
# Install system packages
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
# Make use of apt-cacher-ng if available
|
|
RUN if [ "A${BUILD_APT_PROXY:-}" != "A" ]; then \
|
|
echo "Using APT proxy: ${BUILD_APT_PROXY}"; \
|
|
printf 'Acquire::http::Proxy "%s";\n' "$BUILD_APT_PROXY" > /etc/apt/apt.conf.d/01proxy; \
|
|
fi \
|
|
&& apt-get update \
|
|
&& apt-get install -y --no-install-recommends ca-certificates wget gnupg \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& apt-get clean
|
|
|
|
RUN apt-get update -y --fix-missing --no-install-recommends \
|
|
&& apt-get install -y --no-install-recommends \
|
|
apt-utils \
|
|
locales \
|
|
ca-certificates \
|
|
sudo \
|
|
curl \
|
|
rsync \
|
|
&& apt-get upgrade -y \
|
|
&& apt-get clean \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# UTF-8
|
|
RUN localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
|
|
ENV LANG=en_US.utf8
|
|
ENV LC_ALL=C
|
|
|
|
# Set environment variables
|
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONIOENCODING=utf-8
|
|
|
|
WORKDIR /apptoo
|
|
|
|
# Every sudo group user does not need a password
|
|
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
|
|
|
# Create a new group for the hermeswebui and hermeswebuitoo users
|
|
RUN groupadd -g 1024 hermeswebui \
|
|
&& groupadd -g 1025 hermeswebuitoo
|
|
|
|
# The hermeswebui (resp. hermeswebuitoo) user will have UID 1024 (resp. 1025),
|
|
# be part of the hermeswebui (resp. hermeswebuitoo) and users groups and be sudo capable (passwordless)
|
|
RUN useradd -u 1024 -d /home/hermeswebui -g hermeswebui -s /bin/bash -m hermeswebui \
|
|
&& usermod -G users hermeswebui \
|
|
&& adduser hermeswebui sudo
|
|
RUN useradd -u 1025 -d /home/hermeswebuitoo -g hermeswebuitoo -s /bin/bash -m hermeswebuitoo \
|
|
&& usermod -G users hermeswebuitoo \
|
|
&& adduser hermeswebuitoo sudo
|
|
RUN chown -R hermeswebuitoo:hermeswebuitoo /apptoo
|
|
|
|
USER root
|
|
|
|
COPY --chmod=555 docker_init.bash /hermeswebui_init.bash
|
|
|
|
RUN touch /.within_container
|
|
|
|
# Remove APT proxy configuration and clean up APT downloaded files
|
|
RUN rm -rf /var/lib/apt/lists/* /etc/apt/apt.conf.d/01proxy \
|
|
&& apt-get clean
|
|
|
|
USER root
|
|
|
|
# Pre-install uv system-wide so the container doesn't need internet access at runtime.
|
|
# Installing as root places uv in /usr/local/bin, available to all users.
|
|
# The init script will skip the download when uv is already on PATH.
|
|
RUN curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh
|
|
|
|
USER hermeswebuitoo
|
|
|
|
COPY . /apptoo
|
|
|
|
# Bake the git version tag into the image so the settings badge works even
|
|
# when .git is not present (it is excluded by .dockerignore).
|
|
# CI passes: --build-arg HERMES_VERSION=$(git describe --tags --always)
|
|
# Local builds that omit the arg get "unknown" as the fallback.
|
|
ARG HERMES_VERSION=unknown
|
|
RUN echo "__version__ = '${HERMES_VERSION}'" > /apptoo/api/_version.py
|
|
|
|
# Default to binding all interfaces (required for container networking)
|
|
ENV HERMES_WEBUI_HOST=0.0.0.0
|
|
ENV HERMES_WEBUI_PORT=8787
|
|
|
|
EXPOSE 8787
|
|
|
|
CMD ["/hermeswebui_init.bash"]
|
|
|