fix(release): leak guard + export-ignore + env default (review fixes)
The actual file changes for the leak-safety hardening described in a94efb0
(that commit only captured the art/ asset move):
- promote.sh: leak guard refusing to publish a tree carrying a private identifier
(git.bave.dev / boban/clusev / clusev-staging) or an internal doc; negative test.
- .gitattributes: export-ignore kickoff-prompt.md (leaked the VM IP).
- README: reference the moved art/ SVGs (docs/ is export-ignored).
- .env.example: comment out CLUSEV_REPOSITORY so the public-repo config default
applies (a present-but-empty value would disable the update check).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat/v1-foundation
parent
437221788d
commit
51b8572d98
|
|
@ -85,10 +85,11 @@ ACME_EMAIL=
|
||||||
# .git (the prod image ships none) — leave empty; in dev the page reads .git directly.
|
# .git (the prod image ships none) — leave empty; in dev the page reads .git directly.
|
||||||
CLUSEV_BUILD_SHA=
|
CLUSEV_BUILD_SHA=
|
||||||
CLUSEV_BUILD_BRANCH=
|
CLUSEV_BUILD_BRANCH=
|
||||||
# Update source for the in-app version check. install.sh derives this from the clone origin
|
# Update source for the in-app version check. install.sh sets this from the clone origin
|
||||||
# (git remote get-url origin). Leave empty to disable the check. Never put a private repo URL in a
|
# (git remote get-url origin). Left UNSET (keep this commented), it falls back to the public repo
|
||||||
# tracked file — only here in the per-deployment .env.
|
# default in config/clusev.php — an empty value here would instead disable the check, so leave the
|
||||||
CLUSEV_REPOSITORY=
|
# key absent rather than blank. Never put a private repo URL in a tracked file — only in the .env.
|
||||||
|
# CLUSEV_REPOSITORY=https://github.com/clusev/clusev
|
||||||
# Display timezone for dashboard times (DB stays UTC). install.sh sets this from the host; UTC default.
|
# Display timezone for dashboard times (DB stays UTC). install.sh sets this from the host; UTC default.
|
||||||
APP_TIMEZONE=UTC
|
APP_TIMEZONE=UTC
|
||||||
# External reverse-proxy TLS: set to the upstream proxy's address/CIDR so Caddy trusts its
|
# External reverse-proxy TLS: set to the upstream proxy's address/CIDR so Caddy trusts its
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,5 @@
|
||||||
/CLAUDE.md export-ignore
|
/CLAUDE.md export-ignore
|
||||||
/rules.md export-ignore
|
/rules.md export-ignore
|
||||||
/handoff.md export-ignore
|
/handoff.md export-ignore
|
||||||
|
/kickoff-prompt.md export-ignore
|
||||||
/docs export-ignore
|
/docs export-ignore
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
<img src="docs/assets/clusev-banner.svg" alt="Clusev — self-hosted control plane for a fleet of Linux servers" width="100%">
|
<img src="art/clusev-banner.svg" alt="Clusev — self-hosted control plane for a fleet of Linux servers" width="100%">
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ colour, dots and pills — never emoji.
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="docs/assets/clusev-architecture.svg" alt="Operator → Clusev control plane → your fleet" width="100%">
|
<img src="art/clusev-architecture.svg" alt="Operator → Clusev control plane → your fleet" width="100%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Laravel is the **control plane**, not a re-implementation of your servers. The browser talks to it
|
Laravel is the **control plane**, not a re-implementation of your servers. The browser talks to it
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,23 @@ git -C "$src" archive --format=tar "$tag" | tar -x -C "$pub"
|
||||||
# Private CI never goes public.
|
# Private CI never goes public.
|
||||||
rm -rf "${pub:?}/.github"
|
rm -rf "${pub:?}/.github"
|
||||||
|
|
||||||
|
# Leak guard — never publish a tree that still carries a private identifier or an internal doc. This
|
||||||
|
# makes promote.sh safe even for a tag cut BEFORE the export-ignore / URL-neutralisation fixes: such
|
||||||
|
# a tree is refused (the public repo is left untouched) instead of leaking the dev/staging repos.
|
||||||
|
leak=0
|
||||||
|
for f in CLAUDE.md rules.md handoff.md kickoff-prompt.md docs; do
|
||||||
|
[ -e "$pub/$f" ] && { echo "leak-guard: internal path present in the tree: $f" >&2; leak=1; }
|
||||||
|
done
|
||||||
|
if grep -rIl -e 'git\.bave\.dev' -e 'boban/clusev' -e 'clusev-staging' "$pub" >/dev/null 2>&1; then
|
||||||
|
echo "leak-guard: private repo identifier in the tree to be published:" >&2
|
||||||
|
grep -rIl -e 'git\.bave\.dev' -e 'boban/clusev' -e 'clusev-staging' "$pub" >&2
|
||||||
|
leak=1
|
||||||
|
fi
|
||||||
|
if [ "$leak" -ne 0 ]; then
|
||||||
|
echo "leak-guard: REFUSING to publish $tag — promote a tag cut after the leak-safety fixes (>= v0.9.58)." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
git -C "$pub" add -A
|
git -C "$pub" add -A
|
||||||
# --allow-empty: stable promotion re-tags the same source commit as the last beta, so the
|
# --allow-empty: stable promotion re-tags the same source commit as the last beta, so the
|
||||||
# extracted tree is byte-identical and there is nothing to stage — still produce a release commit.
|
# extracted tree is byte-identical and there is nothing to stage — still produce a release commit.
|
||||||
|
|
|
||||||
|
|
@ -42,4 +42,15 @@ git -C "$work/src" tag v1.0.1 v1.0.0
|
||||||
bash "$here/promote.sh" "$work/src" v1.0.1 "$work/pub" "Release v1.0.1"
|
bash "$here/promote.sh" "$work/src" v1.0.1 "$work/pub" "Release v1.0.1"
|
||||||
git -C "$work/pub" rev-parse v1.0.1 >/dev/null 2>&1 || { echo "FAIL: identical-tree tag missing"; exit 1; }
|
git -C "$work/pub" rev-parse v1.0.1 >/dev/null 2>&1 || { echo "FAIL: identical-tree tag missing"; exit 1; }
|
||||||
git -C "$work/pub" log -1 --pretty=%s | grep -qx 'Release v1.0.1' || { echo "FAIL: identical-tree commit message"; exit 1; }
|
git -C "$work/pub" log -1 --pretty=%s | grep -qx 'Release v1.0.1' || { echo "FAIL: identical-tree commit message"; exit 1; }
|
||||||
|
|
||||||
|
# Leak guard: a tree carrying a private identifier in a PUBLISHED file must be REFUSED, with no tag
|
||||||
|
# created (protects against promoting an old tag cut before the leak-safety fixes).
|
||||||
|
git init -q "$work/leaky"
|
||||||
|
printf 'home: https://git.bave.dev/boban/clusev\n' > "$work/leaky/README.md"
|
||||||
|
git -C "$work/leaky" add -A && git -C "$work/leaky" commit -qm init && git -C "$work/leaky" tag v9.9.9
|
||||||
|
git init -q "$work/pub2"
|
||||||
|
if bash "$here/promote.sh" "$work/leaky" v9.9.9 "$work/pub2" "Release v9.9.9" 2>/dev/null; then
|
||||||
|
echo "FAIL: leak guard did not refuse a private-identifier tree"; exit 1
|
||||||
|
fi
|
||||||
|
git -C "$work/pub2" rev-parse v9.9.9 >/dev/null 2>&1 && { echo "FAIL: tag created despite leak"; exit 1; }
|
||||||
echo "PASS"
|
echo "PASS"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue