7dabcd1317
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Has been skipped
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m23s
The deploy-check skill is repo-specific: it encodes this project's hard-won pre-deploy runtime constraints (distroless nonroot, edge Alt-Svc/HTTP3, caddy recreate, DICT_VERSION boot, expand-contract migrations, the Telegram permission model) and points at deploy/README.md, docs/ARCHITECTURE.md, docs/EDGE_HTTP3.md and the agent memory files. It belongs with the deploy logic it guards, not in the global config, so it travels with the repo and stays versioned alongside it.
90 lines
5.0 KiB
Markdown
90 lines
5.0 KiB
Markdown
---
|
|
name: deploy-check
|
|
description: "Use before any deploy-touching change to this repo — phrases like '/deploy-check', 'is this prod-safe', 'before we deploy', 'deploy safety review', 'проверь перед деплоем', 'это безопасно для прода'. Runs a pre-deploy checklist of this project's hard-won runtime constraints against the current diff, so the crash classes that have bitten live environments get caught before shipping instead of after."
|
|
---
|
|
|
|
# Pre-deploy runtime-constraint check
|
|
|
|
Triggered before shipping anything that touches the deploy contour (Dockerfiles,
|
|
`deploy/`, Caddyfile, compose, migrations, boot guards, the Telegram side-service,
|
|
edge config). The worst frictions in this repo were never logic bugs — they were
|
|
**environment mismatches that crashed a live env and forced a redesign**. Run this
|
|
list against the diff first; turn crash-and-redesign into a single pass.
|
|
|
|
This checklist is a prompt, **not** the source of truth. The canonical detail
|
|
lives in `deploy/README.md`, `docs/ARCHITECTURE.md`, `docs/EDGE_HTTP3.md`, and the
|
|
agent memory files referenced below — read them when an item is in play, and add a
|
|
new class here when a new incident teaches one.
|
|
|
|
## How to run it
|
|
|
|
1. `git diff <base>...HEAD --stat` to see what the change actually touches.
|
|
2. For every risk class below that the diff touches, perform the **Check** and
|
|
report PASS / FAIL with the exact file:line to fix. Skip classes the diff does
|
|
not touch — say which you skipped and why.
|
|
3. Remember: **deploy-job green ≠ healthy**. CI's deploy probe has historically
|
|
passed with a dead backend (it only checked static landing+gateway). Verify the
|
|
real feature live (`/readyz`, the actual flow) after deploy, not just the green.
|
|
|
|
## Risk classes
|
|
|
|
### 1. Container user — distroless nonroot UID 65532
|
|
- **Bit us:** TLS keys `chmod 600` for the host owner crash-looped gateway + bot at
|
|
boot with "permission denied" — service images run UID 65532.
|
|
- **Check:** any new/changed mounted secret, key, or config file must be readable by
|
|
UID 65532 (`0644`, not `0600`). Scan the diff for file modes, `chmod`, and new
|
|
volume mounts. (memory: `distroless-nonroot-mounted-secrets`)
|
|
|
|
### 2. Caddy header pipeline ordering
|
|
- **Bit us:** `header_up delete` after `set` nulled the value (the honeypot tag went
|
|
empty); it passed CI and only showed up live.
|
|
- **Check:** in any Caddyfile change, verify the `set` / `delete` / `header_up`
|
|
ordering for every affected route, and test the tripwire/route on the live
|
|
contour, not just CI.
|
|
|
|
### 3. Edge Alt-Svc / HTTP3
|
|
- **Bit us:** edge advertised `Alt-Svc: h3` while UDP/443 was never exposed
|
|
(docker tcp-only + ufw tcp-only); clients cached it 30 days and stalled on dead
|
|
QUIC before falling back to h2 — Mini App "hangs on load".
|
|
- **Check:** any edge/caddy change keeps `Alt-Svc: clear` (or only advertises h3 if
|
|
UDP/443 is genuinely exposed). (memory: `tg-app-load-stall-dead-http3-altsvc`,
|
|
`docs/EDGE_HTTP3.md`)
|
|
|
|
### 4. Prod caddy config recreate
|
|
- **Bit us:** prod rolling deploy did **not** recreate caddy on a config-only change
|
|
(pinned `caddy:2-alpine` + `admin off`), so a new Caddyfile deployed GREEN but
|
|
stayed inert until a manual `docker restart`.
|
|
- **Check:** a config-only edge change must `--force-recreate` caddy in
|
|
`prod-deploy.sh` `roll()`; never trust deploy-green for edge config.
|
|
(memory: `prod-deploy-caddy-config-recreate`)
|
|
|
|
### 5. DICT_VERSION / dictionary boot
|
|
- **Bit us:** an early `DICT_VERSION` refuse-boot guard was wrong and crashed the
|
|
live env when bumped on a seeded volume; it had to be redesigned to "marker-wins".
|
|
- **Check:** any change touching `DICT_VERSION`, dict load, or the boot guard must
|
|
keep marker-wins semantics and survive a seeded volume **and** an image rollback.
|
|
`DICT_VERSION` is a required build-arg (no default), single-sourced. A new dict
|
|
goes live via the admin console upload, not a redeploy. (memory:
|
|
`dict-version-deploy-verify`, `contour-schema-change-wipe`)
|
|
|
|
### 6. Migrations — expand-contract + rollback safety
|
|
- **Bit us / risk:** a non-backward-compatible migration breaks image rollback (DB
|
|
ahead of rolled-back code).
|
|
- **Check:** migrations must be **expand-contract** (backward-compatible). A schema
|
|
change adds the maintenance window + a consistent `pg_dump` in prod-deploy. On the
|
|
**test contour**, a schema/wire-label change needs `DROP SCHEMA backend CASCADE` +
|
|
backend restart (new code vs old persisted DB), else the contour breaks. (memory:
|
|
`contour-schema-change-wipe`)
|
|
|
|
### 7. Telegram permission model
|
|
- **Bit us:** permissions are an **AND-intersection** — default-allow with explicit
|
|
denies, not default-deny; inverting it broke access.
|
|
- **Check:** any change to the Telegram permission / relay logic preserves the
|
|
AND-intersection default-allow shape. (memory: `telegram-forum-relay-gotchas`)
|
|
|
|
## Output
|
|
|
|
A short PASS/FAIL table over the classes the diff touches, each FAIL with the exact
|
|
file:line and the fix. If every touched class passes, say so plainly and name the
|
|
post-deploy live check to run (not just "CI green").
|