Files
3dealer/bin/deploy
T

121 lines
5.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Deploy this app to production with the latest boboko-core tag.
#
# 1. Refuses to run with uncommitted work (the server deploys what's pushed,
# nothing else) — only the core wiring files are allowed to be dirty.
# 2. Pulls translation lines added in the Language Lines UI into core's
# seeders (boboko:translations:pull) — in local mode; if any are pulled,
# stops so you can release core first. In repo mode it only checks.
# 3. Switches to repo mode if you're on the local ../boboko-core checkout,
# and restarts the stack either way so the lockfiles pick up the newest
# tag (bin/core-mode repo).
# 4. Commits the lockfile bump, if any, asks for confirmation, pushes.
# 5. Runs `envoy run deploy` (see Envoy.blade.php) against .env.envoy's host.
#
# Leaves you in repo mode — run `bin/core-mode local` to go back.
set -euo pipefail
cd "$(dirname "$0")/.."
fail() { echo "!!! $*" >&2; exit 1; }
[ -f .env.envoy ] || fail ".env.envoy not found — copy .env.envoy.example and fill it in."
branch=$(grep -m1 '^DEPLOY_BRANCH=' .env.envoy | cut -d= -f2-)
host=$(grep -m1 '^DEPLOY_SSH_HOST=' .env.envoy | cut -d= -f2-)
branch=${branch:-master}
[ "$(git branch --show-current)" = "$branch" ] || fail "You're not on $branch (the branch Envoy deploys)."
# Anything tracked and modified other than the four core wiring files would be
# silently left out of the deploy — make that a hard stop instead.
dirty=$(git status --porcelain --untracked-files=no |
grep -vE '^.. (composer\.json|composer\.lock|package\.json|package-lock\.json)$' || true)
if [ -n "$dirty" ]; then
echo "$dirty"
fail "Commit or stash these first — the server only deploys what's pushed."
fi
echo ">>> Fetching origin..."
git fetch origin "$branch"
[ "$(git rev-list --count "HEAD..origin/$branch")" -eq 0 ] || fail "origin/$branch has commits you don't — pull first."
# Translation lines added through the Language Lines UI only reach other apps
# once they're in core's seeders. In local mode, pull them into
# ../boboko-core; in repo mode the command can only report them.
lines_in() { printf '%s\n' "$1" | sed -n 's/^\([0-9][0-9]*\) line(s).*/\1/p' | tail -1; }
if [ "$(bin/core-mode)" = local ]; then
echo ">>> Pulling UI-added translations into ../boboko-core's seeders..."
out=$(bin/dc-core.sh exec -T app php artisan boboko:translations:pull --no-ansi) ||
fail "boboko:translations:pull failed — is the stack running (bin/dc-core.sh up -d)?"
echo "$out"
pulled=$(lines_in "$out")
if [ "${pulled:-0}" -gt 0 ]; then
fail "Pulled $pulled translation line(s) into ../boboko-core. Review, commit, tag and push core, then rerun bin/deploy."
fi
else
echo ">>> Checking for UI-added translations missing from core's seeders..."
if out=$(bin/dc exec -T app php artisan boboko:translations:pull --dry-run --no-ansi 2>&1); then
missing=$(lines_in "$out")
if [ "${missing:-0}" -gt 0 ]; then
echo "$out"
fail "These lines are only in this database — run bin/core-mode local and rerun bin/deploy to pull them into core."
fi
echo " nothing missing"
else
echo " skipped — the installed boboko/core doesn't have boboko:translations:pull yet"
fi
fi
# Switch to repo mode (or just restart if already there) so both lockfiles
# resolve the newest boboko-core tag.
bin/core-mode repo
git diff --quiet HEAD -- composer.json package.json ||
fail "composer.json / package.json differ from HEAD in repo mode — they should only differ by the local/repo toggle."
if grep -A14 '"name": "boboko/core"' composer.lock | grep -q '"type": "path"'; then
fail "composer.lock still points boboko/core at the local path repo."
fi
if grep -A6 '"node_modules/@boboko/core": {' package-lock.json | grep -q '"link": true'; then
fail "package-lock.json still links @boboko/core to the local checkout."
fi
version=$(grep -A1 '"name": "boboko/core"' composer.lock | grep -o '"version": "[^"]*"' | cut -d'"' -f4)
# A tag you created in ../boboko-core but never pushed won't be resolved.
if [ -d ../boboko-core ]; then
latest=$(git -C ../boboko-core tag --sort=-v:refname | head -1)
if [ -n "$latest" ] && [ "$latest" != "v$version" ]; then
echo "!!! Warning: resolved boboko/core $version, but ../boboko-core's newest tag is $latest."
echo "!!! Did you push it? (git -C ../boboko-core push origin $latest)"
fi
fi
if ! git diff --quiet HEAD -- composer.lock package-lock.json; then
echo ">>> Committing lockfiles for boboko/core $version..."
git add composer.lock package-lock.json
git commit -m "Chore: Bumping boboko/core to $version"
fi
echo
echo ">>> Deploying $branch to $host with boboko/core $version."
pending=$(git log --oneline "origin/$branch..HEAD")
if [ -n "$pending" ]; then
echo ">>> Commits to push:"
echo "$pending"
else
echo ">>> Nothing new to push — this redeploys origin/$branch as-is."
fi
echo
read -r -p "Push and deploy? [y/N] " answer
[ "$answer" = y ] || [ "$answer" = Y ] || fail "Aborted."
if [ -n "$pending" ]; then
git push origin "$branch"
fi
vendor/bin/envoy run deploy
echo
echo ">>> Done. You're in repo mode — run bin/core-mode local to go back to your ../boboko-core checkout."