deploy: Beförderung gegen Ausweitung sichern (Legende, fremde Beispiele)
Der Umfang war schon richtig — genau eine Datei, kein Glob —, aber als bloße
Zusage zu schwach. `[x]` steht im Repo an Stellen, wo eine Beförderung falsch
bis unsinnig wäre, und der Schaden wäre still:
- Die Legende („Agenda") zeigt `[x] fertig` als ANSCHAUUNGSMATERIAL für die
Notation (index.html, chip('fertig','[x]') in app.js). Daraus würde
„[^] fertig" — Unsinn, den beim Durchsehen eines Diffs niemand bemerkt.
- Das mitgelieferte „Example"-Dokument (INITIAL in app.js) und die übrigen
docs/examples/*.werkbaum sind erfunden.
- SPEC §10 (kanonisches Beispiel, zugleich Test-Fixture) und die Checkboxen in
docs/TASKS.md.
Deshalb jetzt eine Laufzeitsicherung statt einer Absichtserklärung: Der Lauf
vergleicht `git status` vor und nach dem Schreiben und bricht ab, sobald mehr
als die Plandatei NEU geändert ist — Plandatei zurückgesetzt, nichts committet.
Der Vergleich ist gegen den Vorher-Zustand gebildet, damit anderweitig
schmutzige Dateien im Arbeitsbaum keinen Fehlalarm auslösen. Dazu ein
UMFANG-Absatz im Skriptkopf, der die drei Fallen benennt und ausdrücklich sagt:
nicht auf ein Muster erweitern.
Verifiziert im Wegwerf-Worktree: Normalfall befördert die zwei Knoten und
committet; ein absichtlich auf example-plan-0.werkbaum ausgeweiteter sed bricht
mit Exit 1 ab, listet beide betroffenen Dateien, setzt die Plandatei zurück und
committet nichts; danach läuft der Normalfall unverändert durch.
(Beim ersten Testlauf griff der Wächter scheinbar nicht — Ursache war der Test,
nicht das Skript: `git reset --hard` hatte die eingespielte Skriptfassung durch
die committete, noch ungesicherte ersetzt.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6836352e84
commit
cfbbfab54b
+18
-2
@@ -956,8 +956,24 @@ your last visit" (D28) —, nicht das Dutzend, das vorher grob geschätzt worden
|
|||||||
war. Beide stehen jetzt auf `[x]` und leuchten beim nächsten Prod-Deploy als neu
|
war. Beide stehen jetzt auf `[x]` und leuchten beim nächsten Prod-Deploy als neu
|
||||||
auf, was genau der Wahrheit entspricht.
|
auf, was genau der Wahrheit entspricht.
|
||||||
|
|
||||||
**Umfang:** Nur `docs/examples/example-werkbaum.werkbaum`. Die übrigen
|
**Umfang: genau eine Datei, bewusst kein Muster.** Befördert wird nur
|
||||||
Beispieldateien sind erfunden und sagen nichts über ein Deployment aus.
|
`docs/examples/example-werkbaum.werkbaum` — allein der Werkbaum-eigene Plan sagt
|
||||||
|
etwas über das Deployment aus. `[x]` steht im Repo an mehreren Stellen, wo eine
|
||||||
|
Beförderung falsch bis unsinnig wäre:
|
||||||
|
|
||||||
|
- Die **Legende („Agenda")** zeigt `[x] fertig` als *Anschauungsmaterial* für die
|
||||||
|
Notation (`frontend/index.html`, `chip('fertig','[x]')` in `app.js`). Daraus
|
||||||
|
würde `[^] fertig` — Unsinn, den beim Durchsehen eines Diffs niemand bemerkt.
|
||||||
|
- Das mitgelieferte **„Example"-Dokument** (`INITIAL` in `app.js`) und die
|
||||||
|
übrigen `docs/examples/*.werkbaum` sind erfunden.
|
||||||
|
- **SPEC §10** (kanonisches Beispiel, zugleich Test-Fixture) und die Checkboxen
|
||||||
|
in `docs/TASKS.md`.
|
||||||
|
|
||||||
|
Weil eine spätere „Verallgemeinerung" auf ein Glob naheliegt und der Schaden
|
||||||
|
still wäre, bleibt es nicht bei der Zusage: Der Lauf vergleicht `git status` vor
|
||||||
|
und nach dem Schreiben und **bricht ab**, sobald mehr als die Plandatei neu
|
||||||
|
geändert ist — die Datei wird zurückgesetzt, nichts wird committet. Geprüft mit
|
||||||
|
einem absichtlich ausgeweiteten `sed` in einem Wegwerf-Worktree.
|
||||||
|
|
||||||
**Nicht gepusht.** Das Skript committet, pusht aber nicht — Veröffentlichen
|
**Nicht gepusht.** Das Skript committet, pusht aber nicht — Veröffentlichen
|
||||||
bleibt eine bewusste Handlung. `deploy-prod.sh` warnt stattdessen, wenn HEAD
|
bleibt eine bewusste Handlung. `deploy-prod.sh` warnt stattdessen, wenn HEAD
|
||||||
|
|||||||
@@ -22,6 +22,19 @@
|
|||||||
#
|
#
|
||||||
# Ohne zu befördernde Knoten endet der Lauf mit 0 und ändert nichts.
|
# Ohne zu befördernde Knoten endet der Lauf mit 0 und ändert nichts.
|
||||||
# Gepusht wird NICHT — das bleibt eine bewusste Handlung.
|
# Gepusht wird NICHT — das bleibt eine bewusste Handlung.
|
||||||
|
#
|
||||||
|
# UMFANG — bewusst genau EINE Datei, niemals ein Glob:
|
||||||
|
# Nur der Werkbaum-eigene Plan sagt etwas über das Deployment aus. `[x]` steht
|
||||||
|
# im Repo an mehreren Stellen, wo eine Beförderung falsch bis unsinnig wäre:
|
||||||
|
# * die Legende („Agenda") zeigt `[x] fertig` als ANSCHAUUNGSMATERIAL für die
|
||||||
|
# Notation (frontend/index.html, `chip('fertig','[x]')` in app.js) — daraus
|
||||||
|
# würde `[^] fertig`, also Quatsch, den beim Diff niemand bemerkt;
|
||||||
|
# * das mitgelieferte „Example"-Dokument (INITIAL in app.js) und die übrigen
|
||||||
|
# docs/examples/*.werkbaum sind erfunden und beschreiben kein Deployment;
|
||||||
|
# * SPEC §10 (kanonisches Beispiel, zugleich Test-Fixture) und die Checkboxen
|
||||||
|
# in docs/TASKS.md.
|
||||||
|
# Wer diesen Lauf erweitern will, erweitert ihn deshalb NICHT auf ein Muster.
|
||||||
|
# Die Prüfung weiter unten bricht ab, sobald mehr als die Plandatei anders ist.
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -78,13 +91,34 @@ mapfile -t LABELS < <(printf '%s\n' "${HITS[@]}" \
|
|||||||
| sed -E 's/^[0-9]+:[[:space:]]*([-+|][[:space:]]*)?\[[xX]\][[:space:]]*//' \
|
| sed -E 's/^[0-9]+:[[:space:]]*([-+|][[:space:]]*)?\[[xX]\][[:space:]]*//' \
|
||||||
| sed -E 's/[[:space:]]*\((XS|S|M|L|XL|XXL)\)[[:space:]]*$//')
|
| sed -E 's/[[:space:]]*\((XS|S|M|L|XL|XXL)\)[[:space:]]*$//')
|
||||||
|
|
||||||
|
IS_GIT=0
|
||||||
|
git rev-parse HEAD >/dev/null 2>&1 && IS_GIT=1
|
||||||
|
|
||||||
|
BEFORE="$(mktemp)"; AFTER="$(mktemp)"
|
||||||
|
trap 'rm -f "$BEFORE" "$AFTER"' EXIT
|
||||||
|
[ "$IS_GIT" -eq 1 ] && git status --porcelain > "$BEFORE"
|
||||||
|
|
||||||
sed -i -E "s/$MATCH/\1[^]/" "$PLAN"
|
sed -i -E "s/$MATCH/\1[^]/" "$PLAN"
|
||||||
|
|
||||||
if ! git rev-parse HEAD >/dev/null 2>&1; then
|
if [ "$IS_GIT" -eq 0 ]; then
|
||||||
echo "==> Kein Git-Repo — Datei geändert, nicht committet."
|
echo "==> Kein Git-Repo — Datei geändert, nicht committet."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Sicherung gegen künftige Ausweitung (siehe UMFANG oben): Nach dem Schreiben
|
||||||
|
# darf GENAU eine Datei neu geändert sein — die Plandatei. Träfe es zusätzlich
|
||||||
|
# die Legende oder ein fremdes Beispiel, fiele das im Diff kaum auf; hier fällt
|
||||||
|
# es sofort auf.
|
||||||
|
git status --porcelain > "$AFTER"
|
||||||
|
NEU="$(grep -vxF -f "$BEFORE" "$AFTER" | sed -E 's/^.{3}//' || true)"
|
||||||
|
if [ "$NEU" != "$PLAN" ]; then
|
||||||
|
echo " ! Unerwarteter Umfang — geändert wurde:" >&2
|
||||||
|
printf ' %s\n' ${NEU:-"(nichts)"} >&2
|
||||||
|
echo " Erwartet war ausschließlich $PLAN. Nichts committet." >&2
|
||||||
|
git checkout -- "$PLAN"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
{
|
{
|
||||||
echo "docs: Werkbaum-Plan — ${#HITS[@]} Knoten in Produktion"
|
echo "docs: Werkbaum-Plan — ${#HITS[@]} Knoten in Produktion"
|
||||||
echo
|
echo
|
||||||
|
|||||||
Reference in New Issue
Block a user