Make the deploy scripts enforce which branch reaches which server
The rule for this site, stated plainly: only `wj` reaches /shopdb (WJ production), only `dev` reaches /ops, and `main` is the curated release other sites adopt and deploys nowhere. The tooling did not know that, and in two places actively assumed the opposite. export-github.sh refused --dist on any branch but main, because production was assumed to install main. It does not - it installs wj. That guard fired today: a wj export produced its bundle and then died at the dist step, so the dists on the share came from the main export that happened to run next. The code going to production and the frontend going to production would have come from different branches, silently, and nothing downstream could tell. Now one branch builds one dist: wj builds the /shopdb dist, dev builds the /ops dist, and any other branch is refused because a dist it built could only ever be installed by mistake. Each dist carries a .dist-source stamp naming the branch, commit, base path and build time. The two deploy scripts copy from the clone on WHATEVER branch it is sitting on and only ever checked the destination (the web.config mount path), so a clone left on the wrong branch deployed the wrong code to a correctly-identified server without a word. Both now refuse unless the clone is on their branch, and both read the dist's .dist-source and refuse a frontend built from anywhere else. A directory of hashed filenames says nothing about where it came from, and robocopy /MIR will mirror whichever one it is pointed at. pull-shopdb-bundle.cmd and update-shopdb-github.cmd silently defaulted to main. That was safe when main was the only thing anyone deployed; with three branches it is a way to carry the wrong one to a server without ever typing its name. The argument is required now, and the error lists what each branch is for. tools/mirror-wilm.sh is the missing half of fetch-wilm-branch.cmd: that script only puts a bundle on the share, and wilm does not appear on gitea by itself. The new one fetches the carried bundle and pushes wilm to gitea, printing the bundle's age first - a mirror that looks authoritative and is a week old is worse than no mirror - and noting that wilm sits on the publication lineage, so it shares no ancestor with main/wj/dev and cannot be merged here. Scope: product
This commit is contained in:
@@ -265,42 +265,61 @@ git bundle create "$BUNDLE" HEAD "$BRANCH" --tags
|
||||
git bundle verify "$BUNDLE" >/dev/null
|
||||
echo "bundle: $BUNDLE"
|
||||
|
||||
# --- 6. optional per-instance dists (both bases: /ops = dev, /shopdb = prod) ---
|
||||
# Two instances run on the box; each needs its own base-path build. Always
|
||||
# rebuild BOTH so prod never ships a stale frontend.
|
||||
# --dist IS MAIN ONLY.
|
||||
# --- 6. the frontend dist for THIS branch's instance ---------------------------
|
||||
#
|
||||
# These paths are not branch-qualified and cannot safely be: update-prod-server
|
||||
# .cmd robocopies frontend-dist-subpath-shopdb onto the production server with
|
||||
# /MIR, a full mirror, and has no idea which branch built it. So --dist from a
|
||||
# site branch would replace production's frontend with unreleased work at the
|
||||
# next deploy, silently, and the deploy script could not tell.
|
||||
# ONE BRANCH, ONE INSTANCE, ONE DIST. The rule for this site:
|
||||
#
|
||||
# Branch-qualifying the directory would leave the same trap for whoever pointed
|
||||
# a deploy at the wrong one. Production runs the product; a site branch has no
|
||||
# business producing the artefact production installs.
|
||||
if [ "$BUILD_DIST" = 1 ] && [ "$BRANCH" != "main" ]; then
|
||||
# wj -> /shopdb (WJ PRODUCTION) dist: frontend-dist-subpath-shopdb
|
||||
# dev -> /ops (dev instance) dist: frontend-dist-subpath-ops
|
||||
# main -> nothing (curated release other sites adopt)
|
||||
#
|
||||
# This used to build BOTH dists and refuse --dist unless you were on main,
|
||||
# because production was assumed to install main. It does not: production
|
||||
# installs wj. Under the old rule a wj export failed at this step and the
|
||||
# dists on the share came from whichever main export happened to run next -
|
||||
# so the code going to prod and the frontend going to prod came from different
|
||||
# branches, silently, and the deploy scripts could not tell.
|
||||
#
|
||||
# Each dist now carries a .dist-source marker naming the branch, the commit and
|
||||
# the time that built it. update-prod-server.cmd and update-dev-server.cmd read
|
||||
# it and refuse a dist built from the wrong branch, so the trap the old comment
|
||||
# worried about is closed by a check rather than by a convention.
|
||||
case "$BRANCH" in
|
||||
wj) DIST_BASE=shopdb ;;
|
||||
dev) DIST_BASE=ops ;;
|
||||
*) DIST_BASE='' ;;
|
||||
esac
|
||||
|
||||
if [ "$BUILD_DIST" = 1 ] && [ -z "$DIST_BASE" ]; then
|
||||
echo "REFUSED: --dist on branch '$BRANCH'." >&2
|
||||
echo >&2
|
||||
echo "The dist directories are what update-prod-server.cmd mirrors onto the" >&2
|
||||
echo "production server, and they are not branch-qualified. Building them" >&2
|
||||
echo "from '$BRANCH' would put unreleased work on production at the next" >&2
|
||||
echo "deploy, with nothing to reveal it." >&2
|
||||
echo "Only a branch that a server actually runs builds a dist:" >&2
|
||||
echo " wj -> /shopdb (production)" >&2
|
||||
echo " dev -> /ops" >&2
|
||||
echo >&2
|
||||
echo "Promote the commits to main and export from there:" >&2
|
||||
echo " tools/wj-status.sh" >&2
|
||||
echo " tools/promote-to-main.sh <sha> ..." >&2
|
||||
echo "'$BRANCH' deploys nowhere, so a dist built from it could only ever be" >&2
|
||||
echo "installed by mistake. Export it without --dist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$BUILD_DIST" = 1 ]; then
|
||||
cd "$WORK/frontend"
|
||||
for base in ops shopdb; do
|
||||
VITE_BASE_PATH=/$base/ npm run build --silent
|
||||
rm -rf "$OUT/frontend-dist-subpath-$base"
|
||||
cp -r dist "$OUT/frontend-dist-subpath-$base"
|
||||
echo "dist: $OUT/frontend-dist-subpath-$base/ (base /$base/)"
|
||||
done
|
||||
VITE_BASE_PATH=/$DIST_BASE/ npm run build --silent
|
||||
rm -rf "$OUT/frontend-dist-subpath-$DIST_BASE"
|
||||
cp -r dist "$OUT/frontend-dist-subpath-$DIST_BASE"
|
||||
|
||||
# Provenance, read by the deploy scripts. A dist is a directory of hashed
|
||||
# filenames with nothing in it that says where it came from, and robocopy
|
||||
# /MIR will happily mirror the wrong one onto a correctly-identified server.
|
||||
{
|
||||
echo "branch=$BRANCH"
|
||||
echo "commit=$(git -C "$WORK" rev-parse HEAD)"
|
||||
echo "base=/$DIST_BASE/"
|
||||
echo "built=$(date '+%Y-%m-%d %H:%M:%S %z')"
|
||||
echo "host=$(hostname)"
|
||||
} > "$OUT/frontend-dist-subpath-$DIST_BASE/.dist-source"
|
||||
|
||||
echo "dist: $OUT/frontend-dist-subpath-$DIST_BASE/ (base /$DIST_BASE/, from $BRANCH)"
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
|
||||
62
tools/mirror-wilm.sh
Executable file
62
tools/mirror-wilm.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Mirror the wilm branch onto gitea from a bundle carried over from the work PC.
|
||||
#
|
||||
# WHY THIS EXISTS
|
||||
#
|
||||
# wilm is maintained on the corporate GitHub (ge-aero) from the work PC. This
|
||||
# dev box is off the GE network and has no account there, so it can neither
|
||||
# fetch nor push that branch. The only way wilm reaches gitea is:
|
||||
#
|
||||
# 1. WORK PC: fetch-wilm-branch.cmd (read-only, writes the bundle)
|
||||
# 2. Carry shopdb-flask-wilm.bundle onto a drive this PC can read
|
||||
# 3. HERE: tools/mirror-wilm.sh
|
||||
#
|
||||
# Gitea is therefore the mirror of record for wilm and is ALWAYS lagging: it is
|
||||
# only as fresh as the last bundle somebody carried across. This script prints
|
||||
# the bundle's age for exactly that reason - a mirror that looks authoritative
|
||||
# and is a week old is worse than no mirror.
|
||||
#
|
||||
# It never pushes anything TO wilm. That branch belongs to the other site and
|
||||
# merging into it is a work-PC operation against GitHub.
|
||||
set -euo pipefail
|
||||
|
||||
REPO=/home/camp/projects/shopdb-flask
|
||||
BUNDLE="${1:-/home/camp/pxe-images/github/shopdb-flask-wilm.bundle}"
|
||||
|
||||
if [ ! -r "$BUNDLE" ]; then
|
||||
echo "No bundle at $BUNDLE" >&2
|
||||
echo "Run fetch-wilm-branch.cmd on the work PC and copy it across." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! git bundle list-heads "$BUNDLE" | grep -q 'refs/remotes/origin/wilm'; then
|
||||
echo "$BUNDLE does not contain origin/wilm." >&2
|
||||
echo "It is a bundle for something else - do not use it." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
age_days=$(( ( $(date +%s) - $(stat -c %Y "$BUNDLE") ) / 86400 ))
|
||||
echo "Bundle: $BUNDLE"
|
||||
echo "Made: $(stat -c %y "$BUNDLE" | cut -d. -f1) (${age_days} day(s) ago)"
|
||||
if [ "$age_days" -ge 2 ]; then
|
||||
echo "WARNING: this bundle is ${age_days} days old. Whatever it pushes to" >&2
|
||||
echo "gitea will look current and will not be." >&2
|
||||
fi
|
||||
|
||||
cd "$REPO"
|
||||
git fetch "$BUNDLE" 'refs/remotes/origin/wilm:refs/heads/wilm' --force
|
||||
echo "wilm is now $(git log --oneline -1 wilm)"
|
||||
|
||||
# wilm sits on the PUBLICATION lineage (the scrubbed history that goes to
|
||||
# GitHub), which shares no ancestor with our internal main/wj/dev. That is why
|
||||
# the mirror is useful for reading and useless for merging: git will refuse to
|
||||
# merge unrelated histories, and it is right to.
|
||||
if ! git merge-base wilm main >/dev/null 2>&1; then
|
||||
echo
|
||||
echo "NOTE: wilm shares no ancestry with main/wj/dev in this repo - it is on"
|
||||
echo " the publication lineage. Compare it in the publication repo"
|
||||
echo " (/home/camp/projects/shopdb-flask-pub), not here."
|
||||
fi
|
||||
|
||||
"$REPO/tools/git-push.sh" wilm
|
||||
Reference in New Issue
Block a user