chore(deploy): throttle production deploys to one per 24h
The timer deployed on every site-affecting commit at 15 Netlify credits each (~68 deploys / ~1,020 credits in a week). auto-deploy.sh now enforces a minimum gap between successful deploys, default 24h, overridable with SKATESPOTS_DEPLOY_MIN_INTERVAL=<seconds> (0 disables). A throttled tick records nothing so the change still deploys later; failures retry immediately. Deploy on demand with: scripts/auto-deploy.sh --force scripts/docs only — skipped by the timer, so this costs 0 credits.
This commit is contained in:
parent
c89d32d92e
commit
f46f6a8967
2 changed files with 26 additions and 0 deletions
|
|
@ -657,6 +657,7 @@ Rules:
|
|||
|
||||
### Deploy
|
||||
- **Web (auto)**: a systemd user timer (`skatespots-deploy.timer`) runs `scripts/auto-deploy.sh` every ~3 min. When `origin/main` changes it builds and runs `netlify deploy --prod --dir=dist`. It deploys **only committed code** (skips if tracked files are modified) and never mutates a dirty tree. **Doc/scripts-only commits are skipped** (matches `AGENTS.md`/`*.md`/`scripts/`/`cvm-server/`/`skills/`) — Netlify bills **15 credits per production deploy**, so don't spend them on non-site changes. One-time setup: `netlify login` + `netlify link`. Logs: `journalctl --user -u skatespots-deploy`. Manual run: `scripts/auto-deploy.sh`.
|
||||
- ⚠️ **Deploy throttle (2026-09-28):** production deploys are capped to one per **24h** by default (after a week of 68 deploys ≈ **1,020 credits** — a third of the monthly allowance). Batching a day's commits into one 15-credit deploy is the single biggest credit lever. Override with `SKATESPOTS_DEPLOY_MIN_INTERVAL=<seconds>` (`0` disables); deploy on demand with **`scripts/auto-deploy.sh --force`**. A throttled tick deliberately records nothing, so the pending change still deploys on a later tick; a **failed** deploy doesn't set the clock, so it retries immediately.
|
||||
- ⚠️ Shakespeare's "Deploy" rebuilds **its own workspace**, which is NOT updated by git pushes — so pushing to the repo does not change what Shakespeare deploys. Prefer the auto-deploy timer (or drag `dist/` to Netlify).
|
||||
- **Web (manual)**: `npm run build` produces the web `dist/` (with `_headers`/`_redirects`); deploy by dragging `dist/` to the Netlify site's Deploys tab.
|
||||
- **Zapstore (Android)**, from the repo root: `SIGN_WITH='bunker://...' zsp publish zapstore.yaml`
|
||||
|
|
|
|||
|
|
@ -23,8 +23,19 @@ export PATH="/home/sovereignsk8/.nvm/versions/node/v22.23.1/bin:$PATH"
|
|||
STATE_DIR="$HOME/.local/state/skatespots-deploy"
|
||||
SHA_FILE="$STATE_DIR/last-deployed-sha"
|
||||
LOCK_FILE="$STATE_DIR/last-lock-hash"
|
||||
INTERVAL_FILE="$STATE_DIR/last-deploy-epoch"
|
||||
mkdir -p "$STATE_DIR"
|
||||
|
||||
# Production deploys cost 15 Netlify credits each, and this timer polls every
|
||||
# ~3 minutes — so a busy session can spend hundreds of credits on deploys. Enforce
|
||||
# a minimum gap between successful production deploys (default 24h). Override with
|
||||
# SKATESPOTS_DEPLOY_MIN_INTERVAL=<seconds> (0 disables). To deploy immediately,
|
||||
# bypassing the wait: scripts/auto-deploy.sh --force
|
||||
FORCE=0
|
||||
[ "${1:-}" = "--force" ] && FORCE=1
|
||||
MIN_INTERVAL="${SKATESPOTS_DEPLOY_MIN_INTERVAL:-86400}"
|
||||
case "$MIN_INTERVAL" in ''|*[!0-9]*) MIN_INTERVAL=0 ;; esac
|
||||
|
||||
log() { echo "[$(date -Is)] $*"; }
|
||||
|
||||
# Serialise runs (a slow deploy must not overlap the next timer tick).
|
||||
|
|
@ -68,6 +79,19 @@ if [ -n "$LAST_SHA" ] && git cat-file -e "${LAST_SHA}^{commit}" 2>/dev/null; the
|
|||
fi
|
||||
fi
|
||||
|
||||
# 2c. Minimum interval between production deploys (15 credits each). On skip we do
|
||||
# NOT record the SHA, so the pending change is still waiting next tick.
|
||||
if [ "$FORCE" -eq 0 ] && [ "$MIN_INTERVAL" -gt 0 ]; then
|
||||
LAST_EPOCH="$(cat "$INTERVAL_FILE" 2>/dev/null || echo 0)"
|
||||
case "$LAST_EPOCH" in ''|*[!0-9]*) LAST_EPOCH=0 ;; esac
|
||||
ELAPSED=$(( $(date +%s) - LAST_EPOCH ))
|
||||
if [ "$ELAPSED" -lt "$MIN_INTERVAL" ]; then
|
||||
WAIT_MIN=$(( (MIN_INTERVAL - ELAPSED + 59) / 60 ))
|
||||
log "origin/main moved to ${REMOTE_SHA:0:9} but last deploy was $((ELAPSED / 60))m ago — batching (min ${MIN_INTERVAL}s, ~${WAIT_MIN}m left). Use --force to deploy now."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# 3. Move the repo to the published commit (fast-forward only).
|
||||
if [ "$(git rev-parse HEAD)" != "$REMOTE_SHA" ]; then
|
||||
if git merge --ff-only --quiet origin/main; then
|
||||
|
|
@ -106,4 +130,5 @@ log "deploying to Netlify…"
|
|||
netlify deploy --prod --dir=dist
|
||||
|
||||
echo "$REMOTE_SHA" > "$SHA_FILE"
|
||||
date +%s > "$INTERVAL_FILE"
|
||||
log "deployed ${REMOTE_SHA:0:9} ✓"
|
||||
|
|
|
|||
Loading…
Reference in a new issue