Polish GeoIntel workbench and harden Tower deploy
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-28 07:21:48 +02:00
parent 19cf2b5211
commit 438f10fb4b
13 changed files with 1453 additions and 43 deletions
+48 -24
View File
@@ -32,17 +32,57 @@ if ! [[ "$GEOINTEL_APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]
echo "Invalid semantic version in VERSION: ${GEOINTEL_APP_VERSION}" >&2
exit 2
fi
# Hash of everything that actually lands in the image. This is the honest
# answer to "does this image need rebuilding?" — unlike a git SHA, it changes
# when working-tree files change without a commit.
source_tree_hash() {
local hash=""
command -v sha1sum >/dev/null 2>&1 || return 1
hash="$(
find backend frontend deploy scripts fixtures VERSION \
-type f \
! -path '*/node_modules/*' \
! -path '*/dist/*' \
! -path '*/__pycache__/*' \
! -path '*/.pytest_cache/*' \
! -name '*.pyc' \
-print0 2>/dev/null \
| sort -z \
| xargs -0 sha1sum 2>/dev/null \
| sha1sum \
| cut -c1-40
)" || return 1
[ -n "$hash" ] || return 1
printf '%s' "$hash"
}
resolve_build_sha() {
local head="" content=""
# 1. Explicit override wins.
if [ -n "${GEOINTEL_BUILD_SHA:-}" ]; then
printf '%s' "$GEOINTEL_BUILD_SHA"
return 0
fi
# 2. Real git checkout.
# 2. Git checkout, but only when the working tree matches the commit.
# A manually copied tree often carries .git along while the files on disk
# have moved on. Trusting HEAD there produces an unchanged image tag, and
# the deploy silently reuses the previous image instead of rebuilding.
if command -v git >/dev/null 2>&1 && git rev-parse --git-dir >/dev/null 2>&1; then
git rev-parse HEAD
return 0
head="$(git rev-parse HEAD 2>/dev/null || true)"
if [ -n "$head" ]; then
if [ -z "$(git status --porcelain 2>/dev/null)" ]; then
printf '%s' "$head"
return 0
fi
echo "Working tree differs from HEAD; tagging this build by content." >&2
content="$(source_tree_hash || true)"
if [ -n "$content" ]; then
printf '%s-wip%s' "${head:0:12}" "${content:0:12}"
return 0
fi
fi
fi
# 3. Manually copied tree with a RELEASE_SHA marker file.
@@ -51,27 +91,11 @@ resolve_build_sha() {
return 0
fi
# 4. Manually copied tree without git: derive a stable content hash so
# an unchanged redeploy reuses the existing immutable image tag.
if command -v sha1sum >/dev/null 2>&1; then
local tree_hash
tree_hash="$(
find backend frontend deploy scripts fixtures VERSION \
-type f \
! -path '*/node_modules/*' \
! -path '*/__pycache__/*' \
! -path '*/.pytest_cache/*' \
! -name '*.pyc' \
-print0 2>/dev/null \
| sort -z \
| xargs -0 sha1sum 2>/dev/null \
| sha1sum \
| cut -c1-40
)" || tree_hash=""
if [ -n "$tree_hash" ]; then
printf '%s' "$tree_hash"
return 0
fi
# 4. No git: content hash, so an unchanged redeploy still reuses its image.
content="$(source_tree_hash || true)"
if [ -n "$content" ]; then
printf '%s' "$content"
return 0
fi
# 5. Last resort: unique per deploy.