diff --git a/forgejo-instance-setup/SKILL.md b/forgejo-instance-setup/SKILL.md index ba9d8b9..c1f3266 100644 --- a/forgejo-instance-setup/SKILL.md +++ b/forgejo-instance-setup/SKILL.md @@ -1,16 +1,17 @@ --- name: forgejo-instance-setup -description: Set up and work with a Forgejo instance from scratch. Use when creating accounts, configuring tea CLI, generating tokens, or setting up repository workflows on self-hosted Forgejo/Gitea instances. +description: Set up and work with a Forgejo instance from scratch. Includes registration, tea CLI, docker/container paths, API automation, token management, and repository workflows on self-hosted Forgejo/Gitea instances. --- + # Forgejo Instance Setup Skill -This skill provides step-by-step guidance for setting up and working with a Forgejo instance from scratch. +This skill provides step-by-step guidance for setting up and working with a Forgejo instance. ## Directory Structure ``` forgejo-instance-setup/ -├── SKILL.md # This file - main instructions +├── SKILL.md # This file — main instructions ├── scripts/ # Helper scripts (optional) ├── references/ # Detailed reference docs └── assets/ # Templates and resources @@ -20,42 +21,100 @@ forgejo-instance-setup/ ### 1. Create an Account -**Via Web UI:** +**Via Web UI (recommended for humans):** 1. Go to your Forgejo instance URL (e.g., `https://vmd185580.tailf38284.ts.net`) 2. Click **Sign Up** or **Register** 3. Fill in username, email, password 4. Complete CAPTCHA if required -**Note:** Regular users cannot create accounts via API — use the web UI. +> **Note:** Regular users cannot create accounts via API — use the web UI. +> **New instance?** Admin may need to approve/activate your account first. Check if you can log in after registering. + +**Via Web UI programmatically (for agents/bots):** +```bash +# Fetch CSRF token and submit registration +CSRF=$(curl -s -c cookies.txt https:///user/sign_up | \ + grep -oP 'value="\K[^"]+' | head -1) + +curl -s -c cookies.txt -b cookies.txt \ + -X POST https:///user/sign_up \ + -H "x-csrf-token: $CSRF" \ + --data-urlencode "_csrf=$CSRF" \ + --data-urlencode "user_name=my-bot" \ + --data-urlencode "email=bot@example.com" \ + --data-urlencode "password=" \ + --data-urlencode "retype=" +# Expect redirect or flash-message. "already taken" → account exists. +``` ### 2. Install `tea` CLI -**Linux (amd64):** +**Option A — Standard install (with sudo):** ```bash -curl -sL https://github.com/tea-org/tea/releases/latest/download/tea-linux-amd64.tar.gz | tar xz -C /tmp -sudo mv /tmp/tea /usr/local/bin/ -sudo chmod +x /usr/local/bin/tea +# Detect latest version +VERSION=$(curl -s https://dl.gitea.com/tea/ | grep -oP 'href="\K[\d.]+(?=/")' | sort -V | tail -1) +curl -sL -o /usr/local/bin/tea "https://dl.gitea.com/tea/$VERSION/tea-${VERSION}-linux-amd64" +chmod +x /usr/local/bin/tea +``` + +**Option B — No sudo (containers, CI):** +```bash +VERSION=$(curl -s https://dl.gitea.com/tea/ | grep -oP 'href="\K[\d.]+(?=/")' | sort -V | tail -1) +mkdir -p ~/.local/bin +curl -sL -o ~/.local/bin/tea "https://dl.gitea.com/tea/$VERSION/tea-${VERSION}-linux-amd64" +chmod +x ~/.local/bin/tea +# Ensure ~/.local/bin is in PATH ``` **Verify:** ```bash tea --version -# Expected: Version: [1m0.12.0[0m golang: 1.25.7 go-sdk: v0.23.2 +# Example output: Version: [1m0.14.1[0m golang: 1.26.3 go-sdk: v0.25.1 ``` -### 3. Configure Login +### 3. Generate an Access Token -1. Log in to Forgejo web UI → **Settings** → **Application** -2. Click **Add Access Token** -3. Fill in: - - Token name: e.g., `tea-cli` - - Scopes (minimum): `read:user`, `write:repository` -4. Copy the generated token +1. Log in to Forgejo web UI → **Settings** → **Applications** +2. Under **Access Tokens**, enter a name (e.g., `tea-cli`) +3. Select scopes — **recommended:** + - `all` — simplest for autonomous agents + - Or minimal: `read:user`, `write:repository`, `write:issue` +4. Click **Generate Token** +5. **Copy the token immediately** — it is shown only once! -**Save to config (`~/.config/tea/config.yml`):** +**Programmatic token creation (after login):** +```python +import urllib.request, urllib.parse, http.cookiejar, re + +cj = http.cookiejar.CookieJar() +opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) + +# 1. Login +resp = opener.open("https:///user/login") +csrf = re.search(r'value="([^"]+)"', resp.read().decode()).group(1) +data = urllib.parse.urlencode({"_csrf": csrf, "user_name": "my-bot", "password": ""}).encode() +req = urllib.request.Request("https:///user/login", data=data, method='POST') +req.add_header("Content-Type", "application/x-www-form-urlencoded") +opener.open(req) + +# 2. Create token +resp2 = opener.open("https:///user/settings/applications") +csrf2 = re.search(r'value="([^"]+)"', resp2.read().decode()).group(1) +data2 = urllib.parse.urlencode({"_csrf": csrf2, "name": "tea-cli", "scope": "all"}).encode() +req2 = urllib.request.Request("https:///user/settings/applications", data=data2, method='POST') +req2.add_header("Content-Type", "application/x-www-form-urlencoded") +resp3 = opener.open(req2) +html3 = resp3.read().decode() +token = re.search(r'Your new token[^<]*([^<]+)', html3) +if token: print(f"TOKEN: {token.group(1)}") +``` + +### 4. Configure `tea` + +**Save to `~/.config/tea/config.yml`:** ```yaml logins: -- name: +- name: botreasury url: https:// token: default: true @@ -70,76 +129,173 @@ tea whoami # Expected output: # ``` +### 5. Set Up Git (Required!) + +Git needs your identity before you can commit: +```bash +git config --global user.name "Your Name" +git config --global user.email "your@email.com" +``` + +Optional: set `main` as default branch name: +```bash +git config --global init.defaultBranch main +``` + ## Common Tasks ### Create a Repository ```bash +# Create on Forgejo tea repos create --name my-repo \ - --description "My project" \ - --init + --description "My project" + +# Clone and init locally (creates "main" branch) +git clone https://:@//my-repo.git +cd my-repo +echo "# My Project" > README.md +git add README.md +git commit -m "Initial commit" +git push origin main +``` + +**Alternative — local-first, then push:** +```bash +mkdir my-repo && cd my-repo +git init --initial-branch main # or: git init && git branch -m master main +echo "# My Project" > README.md +git add README.md +git commit -m "Initial commit" +tea repos create --name my-repo --description "My project" +git remote add origin https://:@//my-repo.git +git push -u origin main ``` ### Clone a Repository ```bash tea clone username/my-repo -# or with token in URL: +# or with token URL: git clone https://username:@/username/my-repo.git ``` ### Push Changes ```bash git add . -git commit -m "Update" +git commit -m "Describe your change" git push origin main ``` +### Fork and PR +```bash +# Create a fork via API +curl -s -X POST \ + -H "Authorization: token " \ + -H "Content-Type: application/json" \ + "https:///api/v1/repos///forks" \ + -d '{}' + +# Clone your fork, make changes, push +git clone https://:@//.git +cd +# make changes, commit, push + +# Create a pull request via tea +tea pulls create --repo / \ + --title "Your PR title" \ + --description "Description of your changes" \ + --head : \ + --base main + +# Or via API +curl -s -X POST \ + -H "Authorization: token " \ + "https:///api/v1/repos///pulls" \ + -d '{"title":"PR title","body":"PR body","head":":","base":"main"}' +``` + ## Troubleshooting ### Token Scope Errors -If you see `token does not have at least one of required scope(s)`: +`token does not have at least one of required scope(s)`: 1. Go to Forgejo → Settings → Application -2. Edit your token or create a new one -3. Add required scopes (see table below) +2. Generate a new token with required scopes (easiest: `all`) +3. Update `~/.config/tea/config.yml` with the new token + +### Suspended / Inactive Account +- Self-hosted: admin needs to activate your account on the server +- `sudo -u git /app/gitea/gitea admin user activate --username ` + +### No `sudo` Available +Install to `~/.local/bin/` instead of `/usr/local/bin/` + +### `git push` Fails With `src refspec main does not match any` +Your local branch is likely named `master`. Fix: +```bash +git branch -m master main +git push -u origin main +``` +To prevent this: `git config --global init.defaultBranch main` ### Connection Timeouts -- Check instance reachability: `ping ` -- Check TLS: `curl -v https://` -- Check API: `curl https:///api/v1/version` +- Check instance reachability: `curl -sI https://` +- Check API: `curl -s https:///api/v1/version` +- Tailscale/ZeroTier required? Ensure the agent is on the same network. ### Wrong Login Used ```bash tea whoami --login ``` +### Token Not Found in Response +The token is only shown **once** after generation. If you lost it: +1. Delete the old token in Settings → Applications +2. Create a new one + ## Scope Reference | Scope | Description | |-------|-------------| +| `all` | Full access (easiest for bots/agents) | | `read:user` | View user profile and followers | | `write:repository` | Create, update, delete repositories | -| `read:repository` | Read repository contents (public) | +| `read:repository` | Read repository contents | +| `write:issue` | Create and manage issues | -## Example Workflow +## Example Workflow — Full Round Trip ```bash -# 1. Create repo +# 1. Git identity +git config --global user.name "Agent Bot" +git config --global user.email "agent@example.com" +git config --global init.defaultBranch main + +# 2. Create repo tea repos create --name krallen-skills \ --description "Forgejo instance skills" \ --init -# 2. Clone locally -git clone https:///username/krallen-skills.git - -# 3. Add content and push +# 3. Clone +git clone https:////krallen-skills.git cd krallen-skills + +# 4. Add content echo "# Krallen Skills" > README.md git add . git commit -m "Initial commit" git push origin main + +# 5. Later: fork upstream and PR +curl -s -X POST -H "Authorization: token " \ + "https:///api/v1/repos/upstream/repo/forks" -d '{}' +git clone https://@//repo.git +# make changes, commit, push +curl -s -X POST -H "Authorization: token " \ + "https:///api/v1/repos/upstream/repo/pulls" \ + -d '{"title":"Improve X","head":":","base":"main"}' ``` ## References - [Forgejo Documentation](https://forgejo.org/docs/) -- [tea CLI GitHub](https://github.com/tea-org/tea) -- [Gitea API Docs](https://docs.gitea.com/next/api/) +- [tea CLI Downloads](https://dl.gitea.com/tea/) +- [Gitea/Forgejo API Docs](https://docs.gitea.com/next/api/) \ No newline at end of file diff --git a/forgejo-instance-setup/scripts/bootstrap-tea.sh b/forgejo-instance-setup/scripts/bootstrap-tea.sh new file mode 100755 index 0000000..a802999 --- /dev/null +++ b/forgejo-instance-setup/scripts/bootstrap-tea.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# bootstrap-tea.sh — Install tea CLI and configure git for Forgejo +# Usage: ./bootstrap-tea.sh +set -euo pipefail + +INSTANCE="${1:-}" +TOKEN="${2:-}" + +echo "=== Installing tea CLI ===" +VERSION=$(curl -s https://dl.gitea.com/tea/ | grep -oP 'href="\K[\d.]+(?=/")' | sort -V | tail -1) +echo "Latest version: $VERSION" + +if [ -w /usr/local/bin ]; then + TARGET=/usr/local/bin/tea +else + TARGET="$HOME/.local/bin/tea" + mkdir -p "$HOME/.local/bin" + echo "Installing to $TARGET (no sudo)" +fi + +curl -sL -o "$TARGET" "https://dl.gitea.com/tea/$VERSION/tea-${VERSION}-linux-amd64" +chmod +x "$TARGET" +echo "tea installed: $(tea --version)" + +echo "" +echo "=== Git Config ===" +git config --global user.name "Hector Bot" +git config --global user.email "hector-bot@botreasury" +git config --global init.defaultBranch main +echo "Git configured." + +if [ -n "$INSTANCE" ] && [ -n "$TOKEN" ]; then + echo "" + echo "=== Creating tea config ===" + mkdir -p "$HOME/.config/tea" + cat > "$HOME/.config/tea/config.yml" <