mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
## Description Closes #1858 Docker/Compose source builds could report stale or misleading version information: the dashboard initially rendered a hardcoded `v0.3.0`, then `/health` replaced it with installed package metadata, which can be stale when building locally from `main` without release metadata in the image. This change makes source Docker Compose builds report an explicit source-build identity, removes the stale dashboard fallback, and keeps CLI/doctor version checks from treating source-build labels as release-version drift. ## Type of Change - [x] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - Add `HEADROOM_VERSION` / `HEADROOM_BUILD_VERSION` runtime version overrides and optional packaged `_build_info.py` metadata. - Teach Docker Compose source builds to pass a `source-build` sentinel that the Dockerfile expands to `source-build+g<sha>` when git metadata is available, or `source-build+sha256.<digest>` otherwise. - Keep release/published image builds on normal package metadata when `HEADROOM_BUILD_VERSION` is unset. - Include only minimal `.git` metadata in the Docker build context so the source-build label can identify the checkout without copying git objects. - Treat source-build labels and raw hashes as non-release labels in `wrap` and `doctor`, avoiding false stale-proxy restarts and drift warnings. - Replace the dashboard hardcoded `0.3.0` fallback with `loading` / `unknown` and format non-release build labels without a `v` prefix. - Include the runtime version in proxy startup logs, `/health`, `/livez`, and OTEL service version reporting. ## Testing - [x] Unit tests pass (`pytest` in GitHub CI) - [x] Linting passes (`ruff check .`) - [x] Type checking passes (`mypy headroom`) - [x] New tests added for new functionality - [x] Manual testing performed ### Test Output ```text GitHub CI: all checks passing - CI: build, build-wheel, lint, test shards, test-extras, test-agno, test-dashboard-ui - Docker: docker-native-e2e, docker-wrap-e2e, docker-init-e2e - Native wrappers: macOS, Windows, Ubuntu - Security: CodeQL, gitleaks, pip-audit - Governance: template, label, merge-conflicts, commitlint $ HEADROOM_REQUIRE_RUST_CORE=false PYTHONPATH=/Users/vinaygupta/Desktop/git/headroom-fix-1858-version-mismatch pytest tests/test_package_init_lazy.py::test_version_prefers_explicit_build_env tests/test_package_init_lazy.py::test_version_label_helpers_only_prefix_release_versions tests/test_package_init_lazy.py::test_version_uses_packaged_build_metadata tests/test_package_init_lazy.py::test_observability_version_uses_runtime_version tests/test_docker_compose_persistence.py tests/test_cli_doctor.py::TestProxyLiveness::test_up_leaves_source_label_unprefixed tests/test_cli_doctor.py::TestVersionDrift::test_non_release_version_labels_skip_drift_comparison tests/test_cli/test_wrap_persistent.py::test_proxy_version_restart_ignores_non_release_source_labels tests/test_proxy_dashboard_stats_cache.py::test_dashboard_uses_cached_stats_and_lazy_history_feed_polling -q 13 passed, 1 warning $ uvx ruff==0.15.17 check . All checks passed! $ uvx ruff==0.15.17 format --check . 1058 files already formatted $ uvx mypy==1.20.2 headroom --ignore-missing-imports Success: no issues found in 407 source files $ git diff --check # no output $ docker compose config # resolved headroom-proxy build args include HEADROOM_BUILD_VERSION: source-build $ HEADROOM_BUILD_VERSION=6266a1d docker compose config # explicit override is preserved as HEADROOM_BUILD_VERSION: 6266a1d $ docker build --check --build-arg HEADROOM_BUILD_VERSION=source-build . Check complete, no warnings found. ``` ## Real Behavior Proof - Environment: macOS local checkout, Python 3.13.5, Docker Desktop builder `desktop-linux`, plus GitHub Actions CI. - Exact command / steps: `docker compose config`, `HEADROOM_BUILD_VERSION=6266a1d docker compose config`, and `docker build --check --build-arg HEADROOM_BUILD_VERSION=source-build .`. - Observed result: Compose defaults the top-level `headroom-proxy` build arg to the `source-build` sentinel, preserves explicit overrides, and Dockerfile syntax/check validation passes for the source-build path. - Not tested: Full end-to-end release publishing flow; this PR only changes local/source-build reporting. - CI proof: GitHub Actions completed successfully across Docker E2E, CI test shards, lint/type checks, native wrapper checks, security checks, and PR governance. ## Review Readiness - [x] I have performed a self-review - [x] This PR is ready for human review ## Checklist - [x] My code follows the project's style guidelines - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally/CI with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Screenshots (if applicable) N/A ## Additional Notes Docs and changelog are N/A for this runtime-reporting bug fix. The PR is open and ready for review with all GitHub checks passing.
34 lines
1.4 KiB
Python
34 lines
1.4 KiB
Python
"""Regression checks for Docker Compose persistence wiring."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def test_top_level_compose_pins_headroom_state_to_named_volume() -> None:
|
|
compose = (ROOT / "docker-compose.yml").read_text(encoding="utf-8")
|
|
|
|
assert "- headroom_workspace:/home/nonroot/.headroom" in compose
|
|
assert "- HOME=/home/nonroot" in compose
|
|
assert "- HEADROOM_WORKSPACE_DIR=/home/nonroot/.headroom" in compose
|
|
assert "- HEADROOM_CONFIG_DIR=/home/nonroot/.headroom/config" in compose
|
|
|
|
|
|
def test_top_level_compose_marks_source_build_version() -> None:
|
|
compose = (ROOT / "docker-compose.yml").read_text(encoding="utf-8")
|
|
dockerfile = (ROOT / "Dockerfile").read_text(encoding="utf-8")
|
|
dockerignore = (ROOT / ".dockerignore").read_text(encoding="utf-8")
|
|
|
|
assert "HEADROOM_BUILD_VERSION: ${HEADROOM_BUILD_VERSION:-source-build}" in compose
|
|
assert 'ARG HEADROOM_BUILD_VERSION=""' in dockerfile
|
|
assert "ARG PYTHON_SITE_PACKAGES" in dockerfile
|
|
assert "if not build_version:" in dockerfile
|
|
assert "source-build+g{revision}" in dockerfile
|
|
assert "source-build+sha256." in dockerfile
|
|
assert "_build_info.py" in dockerfile
|
|
assert "import headroom._version" not in dockerfile
|
|
assert ".git/*" in dockerignore
|
|
assert "!.git/HEAD" in dockerignore
|
|
assert "!.git/refs/**" in dockerignore
|