Releases: tag each healthy deploy vMAJOR.MINOR.PATCH; /health and node checkin report versions (node-26#49)
Build & Deploy / Build & push images (push) Successful in 4m35s
Build & Deploy / Deploy Firestore rules & indexes (push) Successful in 1m34s
Build & Deploy / Deploy to VM (push) Successful in 1m54s
Build & Deploy / Report a failed deploy (push) Skipped
Build & Deploy / Tag release (push) Successful in 5s
Build & Deploy / Build & push images (push) Successful in 4m35s
Build & Deploy / Deploy Firestore rules & indexes (push) Successful in 1m34s
Build & Deploy / Deploy to VM (push) Successful in 1m54s
Build & Deploy / Report a failed deploy (push) Skipped
Build & Deploy / Tag release (push) Successful in 5s
VERSION holds MAJOR.MINOR (1.1). The build job works out the next patch (scripts/next-version.sh, integer count) and stamps it into c2-core as DRB_VERSION, which /health returns. The new "Tag release" job tags the commit only after the deploy job succeeds, so a failed deploy's number is reused. Node checkins carry `version`, stored on the node doc. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5cdde85d55
commit
b7cdb4452f
@@ -13,5 +13,8 @@ COPY tests/ ./tests/
|
||||
# -- exactly how production served two-day-old code for two days.
|
||||
ARG GIT_SHA=unknown
|
||||
ENV GIT_SHA=$GIT_SHA
|
||||
# The release tag this build becomes (node-26#49), e.g. 1.1.4.
|
||||
ARG DRB_VERSION=untagged
|
||||
ENV DRB_VERSION=$DRB_VERSION
|
||||
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
|
||||
@@ -131,6 +131,7 @@ class MQTTHandler:
|
||||
"sdr_count": payload.get("sdr_count"), # None until reported, never a guessed 1
|
||||
"disk_free_bytes": payload.get("disk_free_bytes"),
|
||||
"disk_total_bytes": payload.get("disk_total_bytes"),
|
||||
"version": payload.get("version"), # installed release (node-26#49)
|
||||
"enforce_override_timeout": payload.get("enforce_override_timeout", True),
|
||||
"is_overridden": False,
|
||||
"override_system_id": None,
|
||||
@@ -168,7 +169,7 @@ class MQTTHandler:
|
||||
# records to — a full disk silently stopped node-002 for 17 days.
|
||||
for key in ("secondary_sdr_mode", "secondary_sdr_priority", "secondary_sdr_running",
|
||||
"sdr_pins", "sdr_devices", "op25_sdr_serial", "radio_channels",
|
||||
"disk_free_bytes", "disk_total_bytes"):
|
||||
"disk_free_bytes", "disk_total_bytes", "version"):
|
||||
if key in payload:
|
||||
updates[key] = payload[key]
|
||||
if "sdr_count" in payload:
|
||||
|
||||
@@ -187,6 +187,7 @@ app.include_router(discord_oauth.router) # auth per-endpoint (org owner / signe
|
||||
# build stamp baked in by the Dockerfile, not configuration anyone sets or
|
||||
# tunes, and keeping it out of Settings avoids implying it can be changed.
|
||||
_GIT_SHA = os.getenv("GIT_SHA", "unknown")
|
||||
_VERSION = os.getenv("DRB_VERSION", "untagged")
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
@@ -197,6 +198,7 @@ async def health():
|
||||
# CI asserts this equals the commit it just deployed. Without it a
|
||||
# deploy can "succeed" while the previous container is still serving.
|
||||
"git_sha": _GIT_SHA,
|
||||
"version": _VERSION,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
"""node-26#49 — releases are visible: /health reports the server's, checkin carries the node's."""
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from app.internal.mqtt_handler import MQTTHandler
|
||||
from app.main import app
|
||||
|
||||
|
||||
def test_health_reports_the_release():
|
||||
with patch("app.main._VERSION", "1.1.4"):
|
||||
body = TestClient(app).get("/health").json()
|
||||
assert body["version"] == "1.1.4"
|
||||
assert "git_sha" in body
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_checkin_stores_the_node_release():
|
||||
with patch("app.internal.mqtt_handler.fstore") as fs:
|
||||
fs.doc_get = AsyncMock(return_value=None)
|
||||
fs.doc_set = AsyncMock()
|
||||
await MQTTHandler()._handle_checkin("n1", {"name": "Pi", "version": "1.1.10"})
|
||||
assert fs.doc_set.call_args[0][2]["version"] == "1.1.10"
|
||||
Reference in New Issue
Block a user