Normalize markdown formatting after the latest main updates.\n\nChecks: python3 scripts/layered_soul.py validate .; npx --yes prettier@3 --check '**/*.md'; git diff --check.
121 lines
4.8 KiB
Markdown
121 lines
4.8 KiB
Markdown
# Self-Hosted Setup & Codeberg Migration
|
|
|
|
Workflow for setting up a self-hosted Forgejo instance and migrating repos from Codeberg.
|
|
|
|
## SSH Setup
|
|
|
|
Forgejo often runs SSH on a non-standard port (e.g. 2222). Always probe:
|
|
|
|
```bash
|
|
ssh -T git@<host> # port 22 — may return password prompt
|
|
ssh -T -p 2222 git@<host> # try 2222
|
|
```
|
|
|
|
Once confirmed, add to `~/.ssh/config`:
|
|
|
|
```
|
|
Host code.<domain>
|
|
HostName code.<domain>
|
|
User git
|
|
Port 2222
|
|
IdentityFile ~/.ssh/<key>
|
|
IdentitiesOnly yes
|
|
```
|
|
|
|
## Org vs User Namespace
|
|
|
|
If the admin account name matches the desired org name (e.g. user `clawdie` cannot have org `clawdie`), repos go under the user: `code.<domain>/clawdie/repo`. Same URL structure, same SSH path. Multi-agent audit trail comes from machine users, not org membership.
|
|
|
|
## Push-to-Create
|
|
|
|
Usually disabled by default. Check:
|
|
|
|
```bash
|
|
# If push fails with "Push to create is not enabled"
|
|
curl -s "https://code.<domain>/api/v1/settings/ui" | jq .
|
|
```
|
|
|
|
Create repos via API or web UI instead.
|
|
|
|
## Shallow Clone → Push (Codeberg Migration)
|
|
|
|
Forgejo rejects shallow pushes unless `ALLOW_SHALLOW_UPDATES` is enabled (off by default). For repos cloned shallow from Codeberg:
|
|
|
|
### Small repos (few commits, full objects present)
|
|
|
|
```bash
|
|
# Check if all objects are present
|
|
git fsck --connectivity-only
|
|
|
|
# Remove shallow marker and rewrite root commit to be parentless
|
|
echo "<root-commit> " > .git/info/grafts
|
|
git filter-branch -f -- --all
|
|
rm .git/info/grafts .git/shallow
|
|
```
|
|
|
|
### Large repos (many objects missing)
|
|
|
|
```bash
|
|
# Fetch full history via HTTPS (more reliable than SSH for large fetches)
|
|
git remote set-url origin https://codeberg.org/<owner>/<repo>.git
|
|
git fetch --unshallow origin
|
|
git remote set-url origin git@codeberg.org:<owner>/<repo>.git # restore
|
|
```
|
|
|
|
## Machine-User Permissions
|
|
|
|
Pattern for multi-agent git access:
|
|
|
|
| User | Host | Permissions |
|
|
| ---------------- | -------- | ---------------------------------- |
|
|
| `<agent>-<host>` | hostname | `write:repository` token + SSH key |
|
|
|
|
- **Never copy private SSH keys** between hosts.
|
|
- Each machine user gets their own SSH key registered on Forgejo.
|
|
- Passwords: only needed if agent uses browser to access web UI (e.g. PR review). Others: random, no force-change.
|
|
- Encode the permissions table in the repo's AGENTS.md for agent self-discovery.
|
|
|
|
## Browser-Based Agent Access
|
|
|
|
Some agents (e.g. Hermes on debby) need web UI access for PR review, issue triage, repo settings, and CI status checks. For these, set a real password (untick "require password change") and store it in Vaultwarden. Other agents (Claude, Codex) only need SSH keys — random passwords are fine.
|
|
|
|
### Password Rotation via Browser
|
|
|
|
When admin-created user has "require password change" ticked, the agent can handle first-login rotation:
|
|
|
|
```bash
|
|
# Generate strong password
|
|
openssl rand -base64 24
|
|
```
|
|
|
|
Then use browser tools to:
|
|
|
|
1. Navigate to `https://code.<domain>/user/login`
|
|
2. Type username + temp password
|
|
3. Forgejo redirects to "Update password" page
|
|
4. Type new password in both fields, submit
|
|
5. Verify landing on dashboard
|
|
|
|
Special characters (šđžčć, etc.) work fine in Forgejo passwords.
|
|
|
|
## Git Hooks Bypass When Node Not on PATH
|
|
|
|
When `node` isn't on PATH (e.g. in a tool-call shell that doesn't source `.bashrc`), git hooks like `pre-commit` and `prepare-commit-msg` hang with `node: not found`. Workaround:
|
|
|
|
```bash
|
|
GIT_AUTHOR_NAME="Name" GIT_AUTHOR_EMAIL="email" \
|
|
GIT_COMMITTER_NAME="Name" GIT_COMMITTER_EMAIL="email" \
|
|
git -c core.hooksPath=/dev/null commit -m "message"
|
|
```
|
|
|
|
Use `--no-verify` only for `pre-commit` and `commit-msg`; `core.hooksPath=/dev/null` kills all hooks including `prepare-commit-msg` which otherwise still fires and hangs.
|
|
|
|
## Pitfalls
|
|
|
|
- **Forgejo SSH on non-standard port**: always probe port 2222 first. The default port 22 often hits system SSH, not Forgejo's, producing confusing password prompts.
|
|
- **Token is immutable**: no edit after creation. Get scopes right on first generate. Wrong scope = new token.
|
|
- **Org name collision with username**: Forgejo won't let you create an org named the same as an existing user. Use the user namespace instead.
|
|
- **Shallow clones from Codeberg**: unshallow before pushing, or rewrite root commits. Forgejo blocks shallow updates by default.
|
|
- **`git fetch --unshallow` timeouts**: Codeberg can be slow. Use HTTPS URL (not SSH) for large unshallow operations — often faster and more reliable.
|
|
- **`git filter-branch` grafts are deprecated**: the `echo "<hash> " > .git/info/grafts` + `git filter-branch -f -- --all` pattern works but is deprecated. Prefer `git replace --convert-graft-file` by default.
|
|
- **Git hooks hang when `node` not on PATH**: use `-c core.hooksPath=/dev/null` (not just `--no-verify` — that skips pre-commit but not prepare-commit-msg).
|