Make the build marker actually report the build
It read 'dev' on the live site, so it was decoration rather than evidence.
Cause: Coolify does not pass a commit SHA into a Docker Compose build, so my
${BUILD_SHA:-dev} fallback always won.
Read from build.txt in the repo instead, which cannot drift from what is
deployed. Two things that took a try each:
- Docker's ENV does not evaluate $(cat file), so the file is copied into the
image and read at startup.
- Streamlit executes app.py in an exec context where __file__ is not
guaranteed; a bare reference to it inside build_sha() would have taken the
whole app down. It now walks a list of candidate paths and never raises.
Verified: docker build ok; build.txt inside the image reads e1f4127;
build_sha() resolves to e1f4127 in the container; the sidebar renders it.
This commit is contained in:
parent
e1f41275ad
commit
7fd221288a
6 changed files with 48 additions and 9 deletions
10
Dockerfile
10
Dockerfile
|
|
@ -19,10 +19,11 @@ ENV PYTHONUNBUFFERED=1 \
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Which build is this? Baked in at image build time so "what am I looking at?"
|
# Which build is this? Read from a file IN the repo rather than a build arg,
|
||||||
# is answerable from the page, not by digging through Coolify's log.
|
# because Coolify does not pass a commit SHA into a Docker Compose build - an
|
||||||
ARG BUILD_SHA=dev
|
# ARG would silently fall back to "dev" forever and the marker would never
|
||||||
ENV BOQ_BUILD_SHA=$BUILD_SHA
|
# tell you anything. Docker's ENV also does not evaluate $(cat ...), so the
|
||||||
|
# file is simply copied and the app reads it at startup.
|
||||||
|
|
||||||
# Dependencies first, so a code change does not reinstall the world.
|
# Dependencies first, so a code change does not reinstall the world.
|
||||||
COPY requirements.txt .
|
COPY requirements.txt .
|
||||||
|
|
@ -32,6 +33,7 @@ COPY app.py run.py ./
|
||||||
COPY boq_engine/ ./boq_engine/
|
COPY boq_engine/ ./boq_engine/
|
||||||
COPY static/ ./static/
|
COPY static/ ./static/
|
||||||
COPY .streamlit/ ./.streamlit/
|
COPY .streamlit/ ./.streamlit/
|
||||||
|
COPY build.txt ./build.txt
|
||||||
|
|
||||||
# Run as a non-root user. UID 1000 matches the usual Coolify/Docker convention.
|
# Run as a non-root user. UID 1000 matches the usual Coolify/Docker convention.
|
||||||
RUN useradd --create-home --uid 1000 --shell /bin/bash megainfra \
|
RUN useradd --create-home --uid 1000 --shell /bin/bash megainfra \
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,11 @@ Anything you disagree with, you settle **in the app** and regenerate. The
|
||||||
consultant never has to leave the screen.
|
consultant never has to leave the screen.
|
||||||
|
|
||||||
Runs entirely on your machine. Nothing is uploaded anywhere. The sidebar shows
|
Runs entirely on your machine. Nothing is uploaded anywhere. The sidebar shows
|
||||||
the build SHA, so you can always see which version you are looking at.
|
the build SHA, so you can always see which version you are looking at. It is
|
||||||
|
read from **`build.txt` in the repo**, not a build argument, because Coolify
|
||||||
|
does not pass a commit SHA into a Docker Compose build — an `ARG` silently
|
||||||
|
falls back to `dev` forever and the marker then tells you nothing.
|
||||||
|
`./update_build_marker.sh` rewrites it; run it as part of committing.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
|
||||||
30
app.py
30
app.py
|
|
@ -110,6 +110,34 @@ def _fp(data: bytes) -> str:
|
||||||
return hashlib.sha256(data).hexdigest()[:16]
|
return hashlib.sha256(data).hexdigest()[:16]
|
||||||
|
|
||||||
|
|
||||||
|
def build_sha() -> str:
|
||||||
|
"""Which build is this? Shown in the sidebar so a deploy can be confirmed
|
||||||
|
without digging through Coolify's log.
|
||||||
|
|
||||||
|
Falls back through several routes because Streamlit executes this file in
|
||||||
|
an exec context where __file__ is not guaranteed - a bare reference to it
|
||||||
|
would take the whole app down. Falls back to the env var, then to a
|
||||||
|
literal, and never raises.
|
||||||
|
"""
|
||||||
|
candidates = []
|
||||||
|
try:
|
||||||
|
candidates.append(os.path.join(
|
||||||
|
os.path.dirname(os.path.abspath(__file__)), "build.txt"))
|
||||||
|
except NameError:
|
||||||
|
pass
|
||||||
|
candidates.append(os.path.join(os.getcwd(), "build.txt"))
|
||||||
|
candidates.append("/app/build.txt")
|
||||||
|
for path in candidates:
|
||||||
|
try:
|
||||||
|
with open(path, encoding="utf-8") as fh:
|
||||||
|
val = fh.read().strip()
|
||||||
|
if val and val != "dev":
|
||||||
|
return val
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
return os.environ.get("BOQ_BUILD_SHA") or "dev"
|
||||||
|
|
||||||
|
|
||||||
def money(v) -> str:
|
def money(v) -> str:
|
||||||
if isinstance(v, (int, float)):
|
if isinstance(v, (int, float)):
|
||||||
return f"R{v:,.2f}"
|
return f"R{v:,.2f}"
|
||||||
|
|
@ -130,7 +158,7 @@ st.markdown(
|
||||||
|
|
||||||
known = profiles.list_profiles()
|
known = profiles.list_profiles()
|
||||||
with st.sidebar:
|
with st.sidebar:
|
||||||
st.caption(f"build {os.environ.get('BOQ_BUILD_SHA', 'dev')}")
|
st.caption(f"build {build_sha()}")
|
||||||
st.subheader("Consultant profile")
|
st.subheader("Consultant profile")
|
||||||
if known:
|
if known:
|
||||||
names = ["— new / not set —"] + [p.consultant for p in known]
|
names = ["— new / not set —"] + [p.consultant for p in known]
|
||||||
|
|
|
||||||
1
build.txt
Normal file
1
build.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
bcba46a
|
||||||
|
|
@ -9,9 +9,6 @@ services:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
|
||||||
# Coolify substitutes the commit it is building
|
|
||||||
BUILD_SHA: "${BUILD_SHA:-dev}"
|
|
||||||
image: mega-infra/boq-converter:latest
|
image: mega-infra/boq-converter:latest
|
||||||
container_name: mega-boq-converter
|
container_name: mega-boq-converter
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
|
||||||
7
update_build_marker.sh
Executable file
7
update_build_marker.sh
Executable file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Rewrite build.txt to the current commit. Run as part of committing, so the
|
||||||
|
# marker in the sidebar always names the build that is actually deployed.
|
||||||
|
# Wired up as a git post-commit hook when the repo is set up locally.
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
git rev-parse --short HEAD > build.txt
|
||||||
Loading…
Reference in a new issue