Add Gitea access, push-to-deploy and domain conventions

This commit is contained in:
2026-10-26 21:41:24 +08:00
parent 0279c3a591
commit 6c11744f80
+108 -2
View File
@@ -1,6 +1,6 @@
--- ---
name: TZGyn-skill name: TZGyn-skill
description: Use proactively for ANY development task in TZGyn's working directories — starting a new project in any language (Go, Rust, TypeScript, not just Swift), cloning/studying/porting a third-party repo (reference material goes in .reference/, never the working root), working in an existing TZGyn repo, creating Gitea repos, publishing to the TZGyn Homebrew tap (casks for GUI apps, formulae for CLIs), signing and notarizing macOS builds, cutting releases, or extending this skill. Load it at the start of any dev session on this machine even when the task doesn't mention Gitea, Homebrew, or macOS. description: Use proactively for ANY development task in TZGyn's working directories — starting a new project in any language (Go, Rust, TypeScript, not just Swift), cloning/studying/porting a third-party repo (reference material goes in .reference/, never the working root), working in an existing TZGyn repo, creating Gitea repos, deploying via Coolify, publishing to the TZGyn Homebrew tap (casks for GUI apps, formulae for CLIs), signing and notarizing macOS builds, cutting releases, or extending this skill. Load it at the start of any dev session on this machine even when the task doesn't mention Gitea, Homebrew, or macOS.
--- ---
# TZGyn dev skill # TZGyn dev skill
@@ -20,7 +20,27 @@ The reference implementations to copy from are `~/Git/kapture` and
to study, port, or compare against go straight into `.reference/` (section to study, port, or compare against go straight into `.reference/` (section
2); waiting until the project is a git repo is too late. 2); waiting until the project is a git repo is too late.
- **Host**: Gitea at `https://gitea.tzgyn.dev`, owner `TZGyn`, `tea` login name - **Host**: Gitea at `https://gitea.tzgyn.dev`, owner `TZGyn`, `tea` login name
`gitea.tzgyn.dev`. SSH: `git@gitea.tzgyn.dev:TZGyn/<repo>.git`. `gitea.tzgyn.dev`. **SSH is on port 22222** (web/API stay on 443):
`ssh://git@gitea.tzgyn.dev:22222/TZGyn/<repo>.git`. Add this to
`~/.ssh/config` so the scp-style URL works without a port:
```sshconfig
Host gitea.tzgyn.dev
Port 22222
User git
```
Then `git@gitea.tzgyn.dev:TZGyn/<repo>.git` is enough. HTTPS remains
`https://gitea.tzgyn.dev/TZGyn/<repo>.git`.
- **Ask for the domain.** If a service needs a public hostname, ask for the
exact domain/subdomain **before** scaffolding or deploying. Never assume
`<service>.tzgyn.dev`, a wildcard, or an existing name. Add/verify the DNS
record, configure it in Coolify's `domains` (HTTP) or the TCP passthrough
labels, and record it in README and AGENTS.
- **Push-to-deploy**: once a repo's Gitea webhook is connected to its Coolify
app, `git push origin main` is the deployment. Do not run a manual deploy for
normal changes; use one only for retries, rollbacks, label/env-only changes,
or webhook failures. See sections 8–9.
- **Always print the upgrade script** (the `brew` commands below) in the final - **Always print the upgrade script** (the `brew` commands below) in the final
answer after any release or version bump. The user wants it every time. answer after any release or version bump. The user wants it every time.
- **Every macOS GUI release must be notarized and stapled.** An unnotarized - **Every macOS GUI release must be notarized and stapled.** An unnotarized
@@ -52,7 +72,10 @@ tea repos create --name <repo> --desc "<one-line description>" --login gitea.tzg
cd ~/Git/<repo> cd ~/Git/<repo>
git init -b main git init -b main
git add -A && git commit -m "<why>" git add -A && git commit -m "<why>"
# HTTPS remote (works with a token/deploy key):
git remote add origin https://gitea.tzgyn.dev/TZGyn/<repo>.git git remote add origin https://gitea.tzgyn.dev/TZGyn/<repo>.git
# or SSH (port 22222 via ~/.ssh/config; explicit form shown in section 9):
# git remote add origin git@gitea.tzgyn.dev:TZGyn/<repo>.git
git push -u origin main git push -u origin main
``` ```
@@ -549,6 +572,10 @@ it). The UI and API are the same deployment.
### Gitea webhook ### Gitea webhook
- **Once this hook is set up and the app is connected, `git push origin main`
is the deployment.** Do not run a manual `POST /deploy` for normal changes;
use it only for retries, rollbacks, label/env-only changes, or webhook
failures. See section 9 for the Gitea side.
- Push-to-deploy uses Coolify's manual Gitea webhook: - Push-to-deploy uses Coolify's manual Gitea webhook:
`X-Hub-Signature-256` = HMAC-SHA256 of the raw body with the app's `X-Hub-Signature-256` = HMAC-SHA256 of the raw body with the app's
`manual_webhook_secret_gitea`; Gitea sends this natively. A curl replay needs `manual_webhook_secret_gitea`; Gitea sends this natively. A curl replay needs
@@ -577,3 +604,82 @@ it). The UI and API are the same deployment.
data volumes. data volumes.
- Verify after deploy: app healthy, the real TCP/SNI path (not just HTTP), - Verify after deploy: app healthy, the real TCP/SNI path (not just HTTP),
custom labels present, and the webhook queued. custom labels present, and the webhook queued.
## 9. Gitea
### Access and remotes
- Web/API: `https://gitea.tzgyn.dev`; owner `TZGyn` is a **user**, not an org.
`tea` login: `gitea.tzgyn.dev`.
- **SSH is on port 22222**, user `git`. Put this in `~/.ssh/config`:
```sshconfig
Host gitea.tzgyn.dev
Port 22222
User git
```
Then `git@gitea.tzgyn.dev:TZGyn/<repo>.git` works. The explicit form is
`ssh://git@gitea.tzgyn.dev:22222/TZGyn/<repo>.git`.
Coolify's `git_repository` often uses the scp-style
`git@gitea.tzgyn.dev:22222/TZGyn/<repo>.git`; Coolify ignores the port when
matching `repository.full_name`, so webhook matching still works.
- HTTPS: `https://gitea.tzgyn.dev/TZGyn/<repo>.git`; private repos need a
deploy key or token. Never commit credentials or put a token in the remote
URL recorded in the repo.
- Create repos with:
```bash
tea repos create --name <repo> --desc "<one-line description>" \
--login gitea.tzgyn.dev
```
Do not pass `--owner TZGyn`: that hits `/orgs/TZGyn/repos` and 404s for a
user.
- Keep repos whose release assets feed Homebrew **public**: `brew` downloads
them without Gitea authentication. Verify with an unauthenticated
`curl -I <release-asset-url>`.
### Push-to-deploy
1. Create the Coolify app from the repo (Dockerfile/build pack) with the deploy
key, the **confirmed domain**, env, and persistent volume (section 8).
2. In the Gitea repo: **Settings → Webhooks → Add webhook → Gitea**.
- URL: `https://coolify.tzgyn.dev/webhooks/source/gitea/events/manual`
- Content type: `application/json`
- Secret: the Coolify app's `manual_webhook_secret_gitea`
- Event: push; branch filter: `main`
3. Push `main`. Gitea signs the raw body with `X-Hub-Signature-256`; Coolify
verifies it and queues the deploy. **This is the normal deployment path —
do not run a manual deploy for a normal push.**
4. Manual `POST /api/v1/deploy?uuid=<app>` only for retries, rollbacks,
label/env-only changes, or webhook failures.
- **Editing a hook's secret through Gitea's API does not update the stored
secret** (PATCH returns 200 but deliveries keep failing). Delete and recreate
the hook. The app's secret is regenerated when the Coolify app is recreated,
so recreate the hook then too.
- Coolify audit log: `webhook.deployment.queued` = accepted;
`webhook.gitea.signature_failed` = secret mismatch.
- A curl replay needs the raw body, `X-Gitea-Event: push`, and a valid
signature.
- Tags do not trigger a `main`-filtered deploy. Push `main` before tagging so
the tag points at the source that shipped.
### Releases and deploy keys
- Release:
```bash
tea releases create --tag v<version> --title "<name> <version>" \
--note-file <notes> --asset <artifact> \
--repo TZGyn/<repo> --login gitea.tzgyn.dev
```
Attach every platform asset and verify by downloading it back and comparing
the checksum.
- Coolify source uses a **deploy key** (the shared `gitea` key by default). Add
its public half to the repo. `private_key_uuid` cannot be changed on an app
update; recreate the app to change keys.
- For a Coolify deployment failure caused by a stale SHA, see the
`uploadpack.allowReachableSHA1InWant` note in section 8.