docs: add Gitea store, dispatch, and server push technique from blog CLAUDE.md
All checks were successful
Deploy Indiekit Server / deploy (push) Successful in 1m16s

This commit is contained in:
2026-03-31 16:12:45 +02:00
parent 78fbd8de8a
commit 373e0c4be8

View File

@@ -195,5 +195,81 @@ npm install git+https://gitea.giersig.eu/svemagie/indiekit-endpoint-activitypub
| `INDIEKIT_BIND_HOST` | Jail IP for webmention poller direct connect |
| `REDIS_URL` | Redis for AP message queue + KV (production; without this, queue lost on restart) |
| `MONGO_HOST` / `MONGO_URL` | MongoDB connection |
| `GH_CONTENT_TOKEN` | GitHub token for writing posts to the `blog` repo |
| `GH_CONTENT_TOKEN` | Gitea PAT for writing posts to the indiekit-blog repo |
| `SECRET` | JWT signing secret (webmention poller auth) |
---
## Content store (Gitea)
`@indiekit/store-github` is pointed at the self-hosted Gitea instance instead of GitHub. Key config in `indiekit.config.mjs`:
```js
"@indiekit/store-github": {
baseUrl: giteaBaseUrl, // GITEA_BASE_URL from .env
user: process.env.GITEA_CONTENT_USER,
repo: process.env.GITEA_CONTENT_REPO,
branch: "main",
token: githubContentToken, // GH_CONTENT_TOKEN from .env
}
```
**`GITEA_BASE_URL`** must end with a trailing slash: `http://10.100.0.90:3000/api/v1/`
Without it, `new URL(apiPath, baseUrl)` silently strips the `v1` segment → 404 on all writes.
**`GH_CONTENT_TOKEN`** — the Gitea PAT for `svemagie`. `start.sh` rejects startup if neither `GH_CONTENT_TOKEN` nor `GITHUB_TOKEN` is present. The token must have repo read/write scope on `giersig.eu/indiekit-blog`.
**`GITEA_CONTENT_USER`** = `giersig.eu` (the org, not the personal username)
**`GITEA_CONTENT_REPO`** = `indiekit-blog`
---
## Micropub → Gitea build dispatch
Gitea Contents API commits (what `store-github` does) do **not** trigger `on: push` CI workflows. `patch-micropub-gitea-dispatch.mjs` patches the Micropub endpoint to fire a `workflow_dispatch` event to `giersig.eu/indiekit-blog` after each create/update, so the blog rebuilds immediately after a post is published.
---
## Pushing changes from the server
The node jail shell is tcsh, which mangles multi-line `echo`/`printf` and inline heredocs. To push file changes to Gitea from the server, use a Python script:
```python
python3 << 'PYEOF'
import urllib.request, json, base64
TOKEN = "your-gitea-pat"
REPO = "giersig.eu/indiekit-blog"
PATH = ".github/workflows/deploy.yml"
BASE = "http://10.100.0.90:3000/api/v1"
# 1. Get current SHA
req = urllib.request.Request(f"{BASE}/repos/{REPO}/contents/{PATH}",
headers={"Authorization": f"token {TOKEN}"})
info = json.loads(urllib.request.urlopen(req).read())
sha = info["sha"]
# 2. Read new content and encode
with open("/path/to/local/file") as f:
content = base64.b64encode(f.read().encode()).decode()
# 3. PUT new content
data = json.dumps({"message": "update file", "content": content, "sha": sha}).encode()
req2 = urllib.request.Request(f"{BASE}/repos/{REPO}/contents/{PATH}",
data=data, method="PUT",
headers={"Authorization": f"token {TOKEN}", "Content-Type": "application/json"})
urllib.request.urlopen(req2)
print("done")
PYEOF
```
Always generate base64 from the actual file — never copy b64 strings from session history (they can be silently corrupted by terminal line wrapping).
For Node.js scripts passed via `bastille cmd node sh -c '...'`, use base64 to avoid quoting issues:
```sh
# On local machine: encode the script
cat script.js | base64 | tr -d '\n'
# On server: decode and run
echo <b64> | b64decode -r > /tmp/script.js && node /tmp/script.js
```