Bot releases install themselves: signed bundle upload to dumpd, no Docker socket in CI
dumpd gains POST /deploy-bot on the bridge-only auth port: HMAC-SHA256 over the body with BOT_DEPLOY_SECRET, a 300 MB cap, one install at a time, and the installer's output returned in the response so the CI job shows it. BOT_DEPLOY_AUTO=0 makes the server refuse. configure.py generates the secret, writes both settings into /etc/vanguard/deploy.env, installs deployBotBundle.sh as /usr/local/bin/vanguard-deploy-bot and creates /srv/bot/app; --show prints what to paste into Gitea. Chose this over mounting the Docker socket into job containers, which would give every CI job root on the host. Also moved threading/subprocess to dumpd's module imports, which the new module-level lock needs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
17
bot/AGENT.md
17
bot/AGENT.md
@@ -43,9 +43,14 @@ Your CI (`.gitea/workflows/ci.yml`, job `bundle`) runs after the tests and produ
|
||||
|
||||
`vendor/` is `pip install --only-binary=:all: --target vendor -r requirements.txt`, built on `python:3.12`
|
||||
so the wheels match the runtime image's ABI. `BUILD.json` records the version, commit, build time, the
|
||||
package list and a sha256 of every file. The admin installs it with `./deployBotBundle.sh <bundle.tar.gz>`,
|
||||
which checks the bundle against `BUILD.json`, keeps the previous release for `--rollback`, and restarts the
|
||||
container. Rules that follow from this:
|
||||
package list and a sha256 of every file.
|
||||
|
||||
**A push to `main` deploys itself.** The workflow's last job posts the bundle to the server's deploy service,
|
||||
signed with the repository secret `BOT_DEPLOY_SECRET`; the server verifies the signature and every checksum,
|
||||
keeps the previous release for rollback, and restarts the container. The install log comes back in your CI
|
||||
job, so a failed deploy fails the run. Branches and pull requests test and build, and deploy nothing.
|
||||
|
||||
Rules that follow from this:
|
||||
|
||||
- Keep `requirements.txt` resolvable with **prebuilt wheels only**; a dependency that must compile will fail
|
||||
the build. Ask the admin if you truly need one.
|
||||
@@ -123,9 +128,9 @@ message content; Message Content is a privileged intent, enable it only if you n
|
||||
|
||||
## 6. Working with the admin
|
||||
|
||||
- **Source**: push to the community Gitea. CI runs your tests on the `python` runner label, then builds the
|
||||
release bundle (§1a); the admin installs it with `deployBotBundle.sh`. Pushes to `main` can install it
|
||||
automatically once the repository variable `BOT_AUTO_DEPLOY` is set to `1`; it is unset by default.
|
||||
- **Source**: push to the community Gitea. CI runs your tests on the `python` runner label, builds the release
|
||||
bundle (§1a), and on `main` installs it on the server. Keep `main` deployable: a red test stops the deploy,
|
||||
and a bundle that fails its checksum check is refused.
|
||||
- **Need infra?** Open a Gitea issue titled `infra: …` stating the exact change: a new env var and why,
|
||||
a mount, a Caddy path that should skip login (e.g. a public webhook endpoint), a new database.
|
||||
Don't work around the proxy or the firewall.
|
||||
|
||||
@@ -5,9 +5,12 @@ Start with **AGENT.md** in this folder: the stack, the rules, the layout, the we
|
||||
## How code reaches the server
|
||||
|
||||
Your repo's Gitea Actions workflow builds a **release bundle**: one tar.gz holding `main.py`, `app/`,
|
||||
`website/`, `version.json`, `BUILD.json` and `vendor/` (your dependencies as prebuilt wheels). The admin
|
||||
installs it with `./deployBotBundle.sh <bundle.tar.gz>` from the stack root; it lands in `/srv/bot/app`,
|
||||
which is bind-mounted into the container at `/app`, and the previous release is kept for `--rollback`.
|
||||
`website/`, `version.json`, `BUILD.json` and `vendor/` (your dependencies as prebuilt wheels). **A push to
|
||||
`main` installs itself**: the workflow's last job posts the bundle to the server's deploy service, which
|
||||
checks its signature and every checksum, swaps it into `/srv/bot/app` (bind-mounted at `/app`, previous
|
||||
release kept for `--rollback`) and restarts the container. The install log comes back in the CI job.
|
||||
|
||||
A branch or pull request runs the tests and builds the artifact, and deploys nothing.
|
||||
|
||||
The image contains **no** bot dependencies: the container imports yours from `/app/vendor`
|
||||
(`PYTHONPATH=/app/vendor`). Adding a dependency means editing `app/requirements.txt` and pushing — no image
|
||||
@@ -15,7 +18,7 @@ rebuild, no package index on the server. The image only changes if you need a ne
|
||||
curl are already there); ask the admin for that.
|
||||
|
||||
## Day to day (on the server, in ~/vanguard-stream)
|
||||
./deployBotBundle.sh vanguard-bot-bundle.tar.gz # install a release
|
||||
./deployBotBundle.sh vanguard-bot-bundle.zip # install a release by hand (zip or tar.gz)
|
||||
./deployBotBundle.sh --status # what is installed; container state
|
||||
./deployBotBundle.sh --rollback # previous release
|
||||
docker compose logs -f discord-bot # live log
|
||||
|
||||
Reference in New Issue
Block a user