krallen-skills/forgejo-instance-setup/SKILL.md

9 KiB

name description
forgejo-instance-setup 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.

Directory Structure

forgejo-instance-setup/
├── SKILL.md           # This file — main instructions
├── scripts/           # Helper scripts (optional)
├── references/        # Detailed reference docs
└── assets/            # Templates and resources

Quick Start

1. Create an Account

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.
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):

# Fetch CSRF token and submit registration
CSRF=$(curl -s -c cookies.txt https://<instance>/user/sign_up | \
  grep -oP 'value="\K[^"]+' | head -1)

curl -s -c cookies.txt -b cookies.txt \
  -X POST https://<instance>/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=<strong-password>" \
  --data-urlencode "retype=<strong-password>"
# Expect redirect or flash-message. "already taken" → account exists.

2. Install tea CLI

Option A — Standard install (with sudo):

# 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):

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:

tea --version
# Example output: Version: [1m0.14.1[0m  golang: 1.26.3  go-sdk: v0.25.1

3. Generate an Access Token

  1. Log in to Forgejo web UI → SettingsApplications
  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!

Programmatic token creation (after login):

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://<instance>/user/login")
csrf = re.search(r'value="([^"]+)"', resp.read().decode()).group(1)
data = urllib.parse.urlencode({"_csrf": csrf, "user_name": "my-bot", "password": "<pw>"}).encode()
req = urllib.request.Request("https://<instance>/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://<instance>/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://<instance>/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[^<]*<strong>([^<]+)</strong>', html3)
if token: print(f"TOKEN: {token.group(1)}")

4. Configure tea

Save to ~/.config/tea/config.yml:

logins:
- name: botreasury
  url: https://<your-forgejo-instance>
  token: <your-token-here>
  default: true
  ssh_host: <your-forgejo-instance>
  user: <username>
  created: <unix-timestamp>

Test connection:

tea whoami
# Expected output: # <username>

5. Set Up Git (Required!)

Git needs your identity before you can commit:

git config --global user.name "Your Name"
git config --global user.email "your@email.com"

Optional: set main as default branch name:

git config --global init.defaultBranch main

Common Tasks

Create a Repository

# Create on Forgejo
tea repos create --name my-repo \
  --description "My project"

# Clone and init locally (creates "main" branch)
git clone https://<username>:<token>@<instance>/<username>/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:

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://<username>:<token>@<instance>/<username>/my-repo.git
git push -u origin main

Clone a Repository

tea clone username/my-repo
# or with token URL:
git clone https://username:<token>@<instance>/username/my-repo.git

Push Changes

git add .
git commit -m "Describe your change"
git push origin main

Fork and PR

# Create a fork via API
curl -s -X POST \
  -H "Authorization: token <your-token>" \
  -H "Content-Type: application/json" \
  "https://<instance>/api/v1/repos/<owner>/<repo>/forks" \
  -d '{}'

# Clone your fork, make changes, push
git clone https://<username>:<token>@<instance>/<username>/<repo>.git
cd <repo>
# make changes, commit, push

# Create a pull request via tea
tea pulls create --repo <owner>/<repo> \
  --title "Your PR title" \
  --description "Description of your changes" \
  --head <username>:<branch> \
  --base main

# Or via API
curl -s -X POST \
  -H "Authorization: token <your-token>" \
  "https://<instance>/api/v1/repos/<owner>/<repo>/pulls" \
  -d '{"title":"PR title","body":"PR body","head":"<username>:<branch>","base":"main"}'

Troubleshooting

Token Scope Errors

token does not have at least one of required scope(s):

  1. Go to Forgejo → Settings → Application
  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 <user>

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:

git branch -m master main
git push -u origin main

To prevent this: git config --global init.defaultBranch main

Connection Timeouts

  • Check instance reachability: curl -sI https://<instance>
  • Check API: curl -s https://<instance>/api/v1/version
  • Tailscale/ZeroTier required? Ensure the agent is on the same network.

Wrong Login Used

tea whoami --login <instance-name>

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
write:issue Create and manage issues

Example Workflow — Full Round Trip

# 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

# 3. Clone
git clone https://<instance>/<username>/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 <token>" \
  "https://<instance>/api/v1/repos/upstream/repo/forks" -d '{}'
git clone https://<token>@<instance>/<username>/repo.git
# make changes, commit, push
curl -s -X POST -H "Authorization: token <token>" \
  "https://<instance>/api/v1/repos/upstream/repo/pulls" \
  -d '{"title":"Improve X","head":"<username>:<branch>","base":"main"}'

References