14daed4c54
Prices were already in the Scryfall bulk download, so this adds no dependency and no new fetch: the work is deciding what a card's price means, given that the index keeps one row per card and a card has many printings. It is the median of the ordinary printings. The kept printing underprices about a third of the legal pool because it is chosen for art and identity and is usually a cheap reprint; the maximum is worse, since premium and bundled listings put a $870 Sol Ring in the data. The median lands where a player recognises the number and ignores the outliers. It is a market value, not a build cost. Two filter decisions are deliberate and easy to undo by accident: Reserved List printings are included, because that is where Commander's banned Power 9 live and excluding them priced Ancestral Recall and Time Walk at nothing, while memorabilia is excluded because a Collectors' Edition box is not a single card. Banned cards fall back to their banned printings. deckValue counts unpriced cards instead of treating them as free, so a total is always labelled with what it left out. Also implements scripts/verify-cards.mjs. package.json and the index skill both documented `pnpm cards:verify` but the script did not exist; it now runs in deploy and fails on a card priced at exactly zero, which is the failure mode the missing-price guard exists to prevent. Co-Authored-By: Claude Code <noreply@anthropic.com>
59 lines
2.1 KiB
Bash
Executable File
59 lines
2.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Build MAGIK, push it to the in-cluster registry and roll it out.
|
|
# Public routing is provided by Caddy on the Oracle VPS and is managed outside
|
|
# this script; calling accessctl here would move DNS back to the Tailnet IP.
|
|
#
|
|
# scripts/deploy.sh [--rebuild-cards]
|
|
#
|
|
# The Scryfall bulk download behind data/cards.db is cached on the host and the
|
|
# image bakes that file in, so a normal deploy touches the network only to push
|
|
# the image. Pass --rebuild-cards to force a fresh download (once per release
|
|
# of the Banned & Restricted List is a sensible cadence; the file is reused).
|
|
set -euo pipefail
|
|
|
|
repo_root="$(cd "$(dirname "$0")/.." && pwd)"
|
|
cd "$repo_root"
|
|
|
|
registry=localhost:32000
|
|
namespace=magik
|
|
subdomain=magic
|
|
|
|
rebuild_cards=0
|
|
for arg in "$@"; do
|
|
case $arg in
|
|
--rebuild-cards) rebuild_cards=1 ;;
|
|
*) echo "unknown option $arg" >&2; exit 64 ;;
|
|
esac
|
|
done
|
|
|
|
# The repo is not a git checkout, so the tag is a timestamp rather than a
|
|
# commit: it still has to change on every release, because the registry keeps
|
|
# :latest and a node that already has it would not re-pull an identical digest.
|
|
tag="${TAG:-$(date -u +%Y%m%d%H%M%S)}"
|
|
|
|
kubectl create namespace "$namespace" --dry-run=client -o yaml | kubectl apply -f -
|
|
|
|
if [[ $rebuild_cards == 1 || ! -f data/cards.db ]]; then
|
|
# The download is cached under data/.cache under the bulk URL's own filename,
|
|
# so a new Scryfall regeneration is picked up on its own; --rebuild-cards
|
|
# exists to force a re-fetch of a URL Scryfall has not re-versioned.
|
|
[[ $rebuild_cards == 1 ]] && rm -rf data/.cache
|
|
pnpm cards:build
|
|
fi
|
|
|
|
pnpm test
|
|
pnpm typecheck
|
|
# The card index is a build artifact, so it is checked like one: a partial
|
|
# download or a poisoned price column would otherwise ship silently.
|
|
pnpm cards:verify
|
|
pnpm build
|
|
|
|
docker build -t "$registry/magic:$tag" "$repo_root"
|
|
docker push "$registry/magic:$tag"
|
|
|
|
sed "s/:latest/:$tag/g" deploy/k8s/magic.yaml | kubectl apply -f -
|
|
kubectl rollout status "deployment/magic" -n "$namespace" --timeout=5m
|
|
|
|
echo "Deployed. Public route: https://$subdomain.marcospaulo.dev.br (Oracle VPS Caddy → homelab over Tailscale)"
|