Repository navigation
Expand file tree
/
Copy pathdeploy
More file actions
executable file
·77 lines (69 loc) · 2.8 KB
/
Copy pathdeploy
File metadata and controls
executable file
·77 lines (69 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env bash
# Build the release dist, stage it into the site repo
# (~/projects/mrfeinberg.com/words/), commit and push that repo, and rsync the
# words/ subtree to the web host.
#
# ./deploy build, stage, commit the site repo, upload
# ./deploy -n build, stage (no commit), rsync dry run
#
# The site repo is the deployed artifact: all of mrfeinberg.com is
# versioned there, words/ included, so every deploy is a commit with
# history and rollback. The remote sync uses the mrfeinberg-claude ssh
# alias (a dedicated key; see ~/.ssh/config) and --delete scoped to
# words/ only — that subtree is fully generated from this repo, so
# deletions in it are always safe. (The site-wide deploy also uses
# --delete, but only from the full local mirror; see
# commands/deploy-mrfeinberg-dot-com.md.)
set -euo pipefail
cd "$(dirname "$0")"
SITE="${WORDS_SITE_DIR:-$HOME/projects/mrfeinberg.com}"
REMOTE="${WORDS_REMOTE:-mrfeinberg-claude:mrfeinberg.com/words/}"
DRY=""
if [ "${1:-}" = "-n" ]; then
DRY="-n"
shift
fi
# Make sure what we stage is the current release build.
export VCPKG_ROOT="${VCPKG_ROOT:-$HOME/vcpkg}"
export EMSDK="${EMSDK:-$HOME/emsdk}"
export PATH="$EMSDK/upstream/emscripten:$PATH"
if [ ! -f build/wasm-release/build.ninja ]; then
cmake --preset wasm-release >/dev/null
fi
cmake --build --preset wasm-release
DIST="$PWD/build/wasm-release/dist"
for f in index.html app.js worker.js words.js words.wasm words.data \
credits.html .htaccess; do
if [ ! -f "$DIST/$f" ]; then
echo "deploy: $DIST/$f missing after build" >&2
exit 1
fi
done
if [ ! -d "$SITE/.jj" ]; then
echo "deploy: $SITE is not the site repo" >&2
exit 1
fi
# Stage: the site repo's words/ mirrors dist exactly. (.DS_Store is
# Finder droppings — excluded here and below, and excluded from
# deletion by the same flag, so it never dirties commits or uploads.)
rsync -a --delete --exclude .DS_Store "$DIST/" "$SITE/words/"
BUILD_ID=$(sed -n "s/.*id: '\([^']*\)'.*/\1/p" "$DIST/build-info.js")
if [ -z "$DRY" ]; then
# Commit the site repo, scoped to words/ (a re-deploy of an unchanged
# build stages nothing and commits nothing). Run from inside the
# repo: jj filesets resolve against the cwd.
if [ -n "$(cd "$SITE" && jj diff --summary words)" ]; then
(cd "$SITE" && jj commit words -m "words build $BUILD_ID")
else
echo "deploy: site repo already at words build $BUILD_ID"
fi
fi
rsync -rlptDv --delete --exclude .DS_Store $DRY "$@" \
"$SITE/words/" "$REMOTE"
# Back the site repo up to GitHub. This runs after the upload so a
# GitHub hiccup can't block a deploy, and it is not `exec`d away: a
# failure here must still surface, because silently skipping the push
# is exactly how the remote drifted nine builds behind the local repo.
if [ -z "$DRY" ]; then
(cd "$SITE" && jj push-main)
fi