Browse Source

Bake .git/HEAD into Docker image so branch detection actually works

  The SpoolBuddy remote-update flow always pulled `main` on the remote
  device when Bambuddy ran under Docker, regardless of which branch the
  image was built from. Root cause: the Dockerfile COPYs only backend/
  and static/, and .dockerignore excluded .git entirely, so the container
  had no git metadata anywhere. detect_current_branch() silently fell
  through its file-read path and returned the GIT_BRANCH env-var default
  of "main".

  The old subprocess-based implementation had the same bug but it was
  masked twice: no .git in the image AND no `git` binary in the image,
  so git rev-parse raised FileNotFoundError, the bare except swallowed
  it, and the fallback kicked in.

  Let the one file we actually need (.git/HEAD — ~20 bytes containing
  `ref: refs/heads/<branch>`) through the .dockerignore filter and COPY
  it into the image at /app/.git/HEAD. detect_current_branch() already
  reads exactly that path, so no Python code changes are needed. Bind-
  mount development setups are unaffected — the bind mount overlays the
  baked-in file with the live repo's .git/HEAD.

  Verified with a throwaway alpine build using the same .dockerignore
  pattern: .git/HEAD passes through, decoy .git/refs and .git/objects
  entries are excluded, and COPY writes the expected content into the
  image.
maziggy 1 month ago
parent
commit
2722ed1538
3 changed files with 17 additions and 1 deletions
  1. 8 1
      .dockerignore
  2. 0 0
      CHANGELOG.md
  3. 9 0
      Dockerfile

+ 8 - 1
.dockerignore

@@ -1,5 +1,12 @@
 # Git
-.git
+# Exclude all .git contents EXCEPT HEAD. HEAD is a tiny text file (under
+# 100 bytes) containing e.g. `ref: refs/heads/dev`, which the Dockerfile
+# copies into the image so detect_current_branch() in spoolbuddy_ssh.py
+# can report the correct branch for SpoolBuddy remote updates. Without
+# this, the production image has no git metadata at all and always falls
+# back to "main" regardless of which branch the operator built from.
+.git/*
+!.git/HEAD
 .gitignore
 
 # Python

File diff suppressed because it is too large
+ 0 - 0
CHANGELOG.md


+ 9 - 0
Dockerfile

@@ -41,6 +41,15 @@ RUN --mount=type=cache,target=/root/.cache/pip \
 # Copy backend
 COPY backend/ ./backend/
 
+# Capture the current git branch at build time. `.git/HEAD` is the only
+# .git metadata the build context lets through (see .dockerignore); it
+# contains `ref: refs/heads/<branch>`, which the SpoolBuddy remote-update
+# flow reads at runtime via detect_current_branch() in spoolbuddy_ssh.py.
+# Without this, the production image has no git metadata at all and would
+# always pull `main` on the remote device regardless of which branch
+# Bambuddy itself was built from.
+COPY .git/HEAD ./.git/HEAD
+
 # Copy built frontend from builder stage
 COPY --from=frontend-builder /app/static ./static
 

Some files were not shown because too many files changed in this diff